diff --git a/AboutThisBuild.txt.in b/AboutThisBuild.txt.in index ea3269c09..f48d39b50 100644 --- a/AboutThisBuild.txt.in +++ b/AboutThisBuild.txt.in @@ -7,6 +7,7 @@ Processor: ${PROC_LABEL} System: ${SYSTEM} Bit depth: ${PROC_BIT_DEPTH} Gtkmm: V${GTKMM_VERSION} +Lensfun: V${LENSFUN_VERSION} Build type: ${BUILD_TYPE} Build flags: ${CXX_FLAGS} Link flags: ${LFLAGS} diff --git a/CMakeLists.txt b/CMakeLists.txt index 685b418bf..d3e2f2c4b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,8 @@ if(WIN32) cmake_minimum_required(VERSION 2.8.4) +elseif(APPLE) + cmake_minimum_required(VERSION 3.3) + CMAKE_POLICY(SET CMP0025 NEW) else() cmake_minimum_required(VERSION 2.6) endif() @@ -54,7 +57,8 @@ set(CACHE_NAME_SUFFIX "" CACHE STRING "RawTherapee's cache folder suffix") 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: -set(RTENGINE_CXX_FLAGS "" 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) @@ -231,6 +235,10 @@ if(NOT DEFINED APPDATADIR) endif() endif() +if(DEFINED LENSFUNDBDIR AND NOT IS_ABSOLUTE "${LENSFUNDBDIR}") + set(LENSFUNDBDIR "${DATADIR}/${LENSFUNDBDIR}") +endif() + # Enforce absolute paths for non-bundle builds: if(NOT BUILD_BUNDLE) foreach(path BINDIR DATADIR LIBDIR DOCDIR CREDITSDIR LICENCEDIR) @@ -262,16 +270,22 @@ endif() # Check for libraries: 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) +else() pkg_check_modules (GTK REQUIRED gtk+-3.0>=3.16) +pkg_check_modules (GTKMM REQUIRED gtkmm-3.0>=3.16) +endif() pkg_check_modules (GLIB2 REQUIRED glib-2.0>=2.44) pkg_check_modules (GLIBMM REQUIRED glibmm-2.4>=2.44) -pkg_check_modules (GTKMM REQUIRED gtkmm-3.0>=3.16) 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) if(WIN32) add_definitions(-DWIN32) @@ -297,6 +311,7 @@ if(WITH_SYSTEM_KLT) find_package(KLT REQUIRED) endif() + # Check for libcanberra-gtk3 (sound events on Linux): if(UNIX AND(NOT APPLE)) pkg_check_modules(CANBERRA-GTK REQUIRED libcanberra-gtk3) @@ -331,6 +346,35 @@ if(OPTION_OMP) endif() endif() +# check for libfftw3f_omp +include(CheckCSourceCompiles) +if(OPENMP_FOUND) + set(CMAKE_REQUIRED_INCLUDES ${FFTW3F_INCLUDE_DIRS}) + set(CMAKE_REQUIRED_LIBRARIES) + foreach(l ${FFTW3F_LIBRARIES}) + find_library(_f ${l} PATHS ${FFTW3F_LIBRARY_DIRS}) + set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${_f}) + endforeach() + check_c_source_compiles( +"#include +int main() +{ + fftwf_init_threads(); + fftwf_plan_with_nthreads(1); + return 0; +}" _fftw3f_multithread) + if(_fftw3f_multithread) + add_definitions(-DRT_FFTW3F_OMP) + else() + find_library(fftw3f_omp fftw3f_omp PATHS ${FFTW3F_LIBRARY_DIRS}) + if(fftw3f_omp) + add_definitions(-DRT_FFTW3F_OMP) + set(FFTW3F_LIBRARIES ${FFTW3F_LIBRARIES} ${fftw3f_omp}) + endif() + endif() +endif() + + # Find out whether we are building out of source: get_filename_component(ABS_SOURCE_DIR "${PROJECT_SOURCE_DIR}" ABSOLUTE) get_filename_component(ABS_BINARY_DIR "${CMAKE_BINARY_DIR}" ABSOLUTE) @@ -389,7 +433,8 @@ set(ABOUT_COMMAND_WITH_ARGS ${CMAKE_COMMAND} -DBUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} -DGTKMM_VERSION:STRING=${GTKMM_VERSION} -DOPTION_OMP:STRING=${OPTION_OMP} - -DWITH_MYFILE_MMAP:STRING=${WITH_MYFILE_MMAP}) + -DWITH_MYFILE_MMAP:STRING=${WITH_MYFILE_MMAP} + -DLENSFUN_VERSION:STRING=${LENSFUN_VERSION}) if(WIN32) list(APPEND ABOUT_COMMAND_WITH_ARGS -DSYSTEM:STRING=Windows @@ -439,6 +484,34 @@ if(UNIX) install(FILES rawtherapee.appdata.xml DESTINATION "${APPDATADIR}") endif() +# check whether the used version of lensfun has lfDatabase::LoadDirectory +include(CheckCXXSourceCompiles) +set(CMAKE_REQUIRED_INCLUDES ${LENSFUN_INCLUDE_DIRS}) +set(CMAKE_REQUIRED_LIBRARIES) +foreach(l ${LENSFUN_LIBRARIES}) + if(LENSFUN_LIBRARY_DIRS) + # the NO_DEFAULT_PATH is to make sure we find the lensfun version we + # want, and not the system's one (e.g. if we have a custom version + # installed in a non-standard location) + find_library(_l ${l} PATHS ${LENSFUN_LIBRARY_DIRS} NO_DEFAULT_PATH) + else() + # LENSFUN_LIBRARY_DIRS can be empty if lensfun is installed in the + # default path. In this case, adding NO_DEFAULT_PATH would make + # find_library fail... + find_library(_l ${l}) + endif() + set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${_l}) +endforeach() +check_cxx_source_compiles( + "#include +int main() +{ + lfDatabase *db = 0; + bool b = db->LoadDirectory(0); + return 0; +}" LENSFUN_HAS_LOAD_DIRECTORY) + + add_subdirectory(rtexif) add_subdirectory(rtengine) add_subdirectory(rtgui) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5cdfd8d5b..257eb9708 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -14,6 +14,7 @@ The most useful feedback is based on the latest development code, and in the cas ## Contributing as a Programmer - Announce and discuss your plans in GitHub before starting work. +- Work in a new branch. Fork if necessary. - Keep branches small so that completed and working features can be merged into the "dev" branch often, and so that they can be abandoned if they head in the wrong direction. - Use C++11 -- Code must be run through astyle version 3 or newer before being merged. +- Code may be run through astyle version 3 or newer. If using astyle, it is important that the astyle changes go into their own commit, so that style changes are not mixed with actual code changes. Command: `astyle --options=rawtherapee.astylerc code.cc` diff --git a/RELEASE_NOTES.txt b/RELEASE_NOTES.txt index 5affd4b39..ee44c6de1 100644 --- a/RELEASE_NOTES.txt +++ b/RELEASE_NOTES.txt @@ -1,8 +1,8 @@ -RAWTHERAPEE 5.2 RELEASE NOTES +RAWTHERAPEE 5.3-dev RELEASE NOTES ----------------------------- This is a development version of RawTherapee. We update the code almost daily. Every few months, once enough changes have accumulated and the code is stabilized, we make a new official release. Every code change between these releases is known as a "development" version, and this is one of them. -RawTherapee provides you with a selection of powerful tools with which you can practice the art of developing raw photos. Be sure to read RawPedia to understand how each tool works so that you may make the most of it. +RawTherapee provides you with a selection of powerful tools with which you can practise the art of developing raw photos. Be sure to read RawPedia to understand how each tool works so that you may make the most of it. http://rawpedia.rawtherapee.com/ A great place to start is the "Getting Started" article. Click on "Main page" in the top-left corner when you have finished reading that article to see all other articles. @@ -15,7 +15,8 @@ While we only commit tested and relatively stable code and so the development ve News Relevant to Photographers ------------------------------ -RawTherapee supports most raw formats, including some unusual ones like those from cameras using Foveon and X-Trans sensors. If you're wondering whether it supports your camera's raw format, first download RawTherapee and try for yourself. If a raw format is not supported it will either not open, or the preview in the Editor tab will appear black, white, or have a strong color cast - usually magenta. In that case, read the "Adding Support for New Raw Formats" RawPedia article. +RawTherapee supports most raw formats, including Pentax Pixel Shift, Canon Dual-Pixel, and those from Foveon and X-Trans sensors. +If you're wondering whether it supports your camera's raw format, first download RawTherapee and try for yourself. If a raw format is not supported it will either not open, or the preview in the Editor tab will appear black, white, or have a strong color cast - usually magenta. In that case, read the "Adding Support for New Raw Formats" RawPedia article. In order to use RawTherapee efficiently you should know that: - You can scroll all panels using the mouse scroll-wheel. @@ -24,8 +25,8 @@ In order to use RawTherapee efficiently you should know that: - All curves support the Shift and Ctrl keys while dragging a point. Shift+drag makes the point snap to meaningful axes (top, bottom, diagonal, other), while Ctrl+drag makes your mouse movement super-fine for precise point positioning. - There are many keyboard shortcuts which make working with RawTherapee much faster and give you greater control. Make sure you familiarize yourself with them on RawPedia's "Keyboard Shortcuts" page! -New features since 5.2: -- To be filled in once 5.3 is released. +New features since 5.3: +- To be filled in when 5.4 is released. News Relevant to Package Maintainers ------------------------------------ @@ -38,14 +39,13 @@ In general: - For development builds and release-candidates use -DCACHE_NAME_SUFFIX="5-dev" Changes since 5.2: -- To be filled in once 5.3 is released. +- To be filled in when 5.4 is released. News Relevant to Developers --------------------------- - Announce and discuss your plans in GitHub before starting work. - Keep branches small so that completed and working features can be merged into the "dev" branch often, and so that they can be abandoned if they head in the wrong direction. - Use C++11. -- Code must be run through astyle. DOCUMENTATION ------------- diff --git a/licenses/osx_libiomp5_LICENSE.txt b/licenses/osx_libiomp5_LICENSE.txt new file mode 100644 index 000000000..18fca0d43 --- /dev/null +++ b/licenses/osx_libiomp5_LICENSE.txt @@ -0,0 +1,27 @@ +Copyright (c) 2013-2016, Intel Corporation +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/rtdata/dcpprofiles/Canon EOS 1300D.dcp b/rtdata/dcpprofiles/Canon EOS 1300D.dcp new file mode 100644 index 000000000..e6fa7ac41 Binary files /dev/null and b/rtdata/dcpprofiles/Canon EOS 1300D.dcp differ diff --git a/rtdata/dcpprofiles/Canon EOS 60D.dcp b/rtdata/dcpprofiles/Canon EOS 60D.dcp new file mode 100644 index 000000000..24e7e04b6 Binary files /dev/null and b/rtdata/dcpprofiles/Canon EOS 60D.dcp differ diff --git a/rtdata/dcpprofiles/Canon EOS 6D Mark II.dcp b/rtdata/dcpprofiles/Canon EOS 6D Mark II.dcp new file mode 100644 index 000000000..69a131bd3 Binary files /dev/null and b/rtdata/dcpprofiles/Canon EOS 6D Mark II.dcp differ diff --git a/rtdata/dcpprofiles/NIKON D700.dcp b/rtdata/dcpprofiles/NIKON D700.dcp new file mode 100644 index 000000000..1ae994439 Binary files /dev/null and b/rtdata/dcpprofiles/NIKON D700.dcp differ diff --git a/rtdata/dcpprofiles/Nikon D700.dcp b/rtdata/dcpprofiles/Nikon D700.dcp deleted file mode 100644 index 969c6b964..000000000 Binary files a/rtdata/dcpprofiles/Nikon D700.dcp and /dev/null differ diff --git a/rtdata/dcpprofiles/Panasonic DC-TZ90.dcp b/rtdata/dcpprofiles/Panasonic DC-TZ90.dcp new file mode 100644 index 000000000..2a3abfaed Binary files /dev/null and b/rtdata/dcpprofiles/Panasonic DC-TZ90.dcp differ diff --git a/rtdata/dcpprofiles/Panasonic DC-TZ91.dcp b/rtdata/dcpprofiles/Panasonic DC-TZ91.dcp new file mode 100644 index 000000000..2a3abfaed Binary files /dev/null and b/rtdata/dcpprofiles/Panasonic DC-TZ91.dcp differ diff --git a/rtdata/dcpprofiles/Panasonic DC-TZ92.dcp b/rtdata/dcpprofiles/Panasonic DC-TZ92.dcp new file mode 100644 index 000000000..2a3abfaed Binary files /dev/null and b/rtdata/dcpprofiles/Panasonic DC-TZ92.dcp differ diff --git a/rtdata/dcpprofiles/Panasonic DC-TZ93.dcp b/rtdata/dcpprofiles/Panasonic DC-TZ93.dcp new file mode 100644 index 000000000..2a3abfaed Binary files /dev/null and b/rtdata/dcpprofiles/Panasonic DC-TZ93.dcp differ diff --git a/rtdata/iccprofiles/output/ACES.icc b/rtdata/iccprofiles/output/ACES.icc new file mode 100644 index 000000000..cb87b8bf2 Binary files /dev/null and b/rtdata/iccprofiles/output/ACES.icc differ diff --git a/rtdata/iccprofiles/output/DCI-P3 D65.icc b/rtdata/iccprofiles/output/DCI-P3 D65.icc new file mode 100644 index 000000000..195bf7a1d Binary files /dev/null and b/rtdata/iccprofiles/output/DCI-P3 D65.icc differ diff --git a/rtdata/iccprofiles/output/DCI-P3 Theater.icc b/rtdata/iccprofiles/output/DCI-P3 Theater.icc new file mode 100644 index 000000000..90ccbc69c Binary files /dev/null and b/rtdata/iccprofiles/output/DCI-P3 Theater.icc differ diff --git a/rtdata/images/Dark/actions/HDR-thumbnail.png b/rtdata/images/Dark/actions/HDR-thumbnail.png new file mode 100644 index 000000000..182e603e8 Binary files /dev/null and b/rtdata/images/Dark/actions/HDR-thumbnail.png differ diff --git a/rtdata/images/Dark/actions/PixelShift-thumbnail.png b/rtdata/images/Dark/actions/PixelShift-thumbnail.png new file mode 100644 index 000000000..4bbea1aee Binary files /dev/null and b/rtdata/images/Dark/actions/PixelShift-thumbnail.png differ diff --git a/rtdata/images/Dark/actions/previewmodeB-off.png b/rtdata/images/Dark/actions/previewmodeB-off.png index 1ff087b4d..0c9890437 100644 Binary files a/rtdata/images/Dark/actions/previewmodeB-off.png and b/rtdata/images/Dark/actions/previewmodeB-off.png differ diff --git a/rtdata/images/Dark/actions/previewmodeB-on.png b/rtdata/images/Dark/actions/previewmodeB-on.png index 6403fc722..466192b3a 100644 Binary files a/rtdata/images/Dark/actions/previewmodeB-on.png and b/rtdata/images/Dark/actions/previewmodeB-on.png differ diff --git a/rtdata/images/Dark/actions/previewmodeBC0-off.png b/rtdata/images/Dark/actions/previewmodeBC0-off.png index 05a75ee25..28c024555 100644 Binary files a/rtdata/images/Dark/actions/previewmodeBC0-off.png and b/rtdata/images/Dark/actions/previewmodeBC0-off.png differ diff --git a/rtdata/images/Dark/actions/previewmodeBC0-on.png b/rtdata/images/Dark/actions/previewmodeBC0-on.png index a1f462cb2..f5e0b8000 100644 Binary files a/rtdata/images/Dark/actions/previewmodeBC0-on.png and b/rtdata/images/Dark/actions/previewmodeBC0-on.png differ diff --git a/rtdata/images/Dark/actions/previewmodeBC1-off.png b/rtdata/images/Dark/actions/previewmodeBC1-off.png index d5071108a..4ac160b05 100644 Binary files a/rtdata/images/Dark/actions/previewmodeBC1-off.png and b/rtdata/images/Dark/actions/previewmodeBC1-off.png differ diff --git a/rtdata/images/Dark/actions/previewmodeBC1-on.png b/rtdata/images/Dark/actions/previewmodeBC1-on.png index f71b27965..3e9b6874c 100644 Binary files a/rtdata/images/Dark/actions/previewmodeBC1-on.png and b/rtdata/images/Dark/actions/previewmodeBC1-on.png differ diff --git a/rtdata/images/Dark/actions/previewmodeBC2-off.png b/rtdata/images/Dark/actions/previewmodeBC2-off.png index 5c9b2d0e8..bf3d97b2d 100644 Binary files a/rtdata/images/Dark/actions/previewmodeBC2-off.png and b/rtdata/images/Dark/actions/previewmodeBC2-off.png differ diff --git a/rtdata/images/Dark/actions/previewmodeBC2-on.png b/rtdata/images/Dark/actions/previewmodeBC2-on.png index 8f5b9207e..457453166 100644 Binary files a/rtdata/images/Dark/actions/previewmodeBC2-on.png and b/rtdata/images/Dark/actions/previewmodeBC2-on.png differ diff --git a/rtdata/images/Dark/actions/previewmodeBC3-off.png b/rtdata/images/Dark/actions/previewmodeBC3-off.png new file mode 100644 index 000000000..487ec777e Binary files /dev/null and b/rtdata/images/Dark/actions/previewmodeBC3-off.png differ diff --git a/rtdata/images/Dark/actions/previewmodeBC3-on.png b/rtdata/images/Dark/actions/previewmodeBC3-on.png new file mode 100644 index 000000000..670b5b8b4 Binary files /dev/null and b/rtdata/images/Dark/actions/previewmodeBC3-on.png differ diff --git a/rtdata/images/Dark/actions/previewmodeF-focusScreen-off.png b/rtdata/images/Dark/actions/previewmodeF-focusScreen-off.png new file mode 100644 index 000000000..75a285de2 Binary files /dev/null and b/rtdata/images/Dark/actions/previewmodeF-focusScreen-off.png differ diff --git a/rtdata/images/Dark/actions/previewmodeF-focusScreen-on.png b/rtdata/images/Dark/actions/previewmodeF-focusScreen-on.png new file mode 100644 index 000000000..3d46dedc7 Binary files /dev/null and b/rtdata/images/Dark/actions/previewmodeF-focusScreen-on.png differ diff --git a/rtdata/images/Dark/actions/previewmodeF-off.png b/rtdata/images/Dark/actions/previewmodeF-off.png index 519de02bc..5d52af569 100644 Binary files a/rtdata/images/Dark/actions/previewmodeF-off.png and b/rtdata/images/Dark/actions/previewmodeF-off.png differ diff --git a/rtdata/images/Dark/actions/previewmodeF-on.png b/rtdata/images/Dark/actions/previewmodeF-on.png index 3910e6a20..f0d0ef230 100644 Binary files a/rtdata/images/Dark/actions/previewmodeF-on.png and b/rtdata/images/Dark/actions/previewmodeF-on.png differ diff --git a/rtdata/images/Dark/actions/previewmodeG-off.png b/rtdata/images/Dark/actions/previewmodeG-off.png index e25911324..5c076c989 100644 Binary files a/rtdata/images/Dark/actions/previewmodeG-off.png and b/rtdata/images/Dark/actions/previewmodeG-off.png differ diff --git a/rtdata/images/Dark/actions/previewmodeG-on.png b/rtdata/images/Dark/actions/previewmodeG-on.png index db31667ed..ecc75c8e7 100644 Binary files a/rtdata/images/Dark/actions/previewmodeG-on.png and b/rtdata/images/Dark/actions/previewmodeG-on.png differ diff --git a/rtdata/images/Dark/actions/previewmodeL-off.png b/rtdata/images/Dark/actions/previewmodeL-off.png index d24dea76f..939dec642 100644 Binary files a/rtdata/images/Dark/actions/previewmodeL-off.png and b/rtdata/images/Dark/actions/previewmodeL-off.png differ diff --git a/rtdata/images/Dark/actions/previewmodeL-on.png b/rtdata/images/Dark/actions/previewmodeL-on.png index 11b745e09..92fe937e8 100644 Binary files a/rtdata/images/Dark/actions/previewmodeL-on.png and b/rtdata/images/Dark/actions/previewmodeL-on.png differ diff --git a/rtdata/images/Dark/actions/previewmodeR-off.png b/rtdata/images/Dark/actions/previewmodeR-off.png index 9aef77301..b96e22c31 100644 Binary files a/rtdata/images/Dark/actions/previewmodeR-off.png and b/rtdata/images/Dark/actions/previewmodeR-off.png differ diff --git a/rtdata/images/Dark/actions/previewmodeR-on.png b/rtdata/images/Dark/actions/previewmodeR-on.png index 5fb0f996e..fb1e46e98 100644 Binary files a/rtdata/images/Dark/actions/previewmodeR-on.png and b/rtdata/images/Dark/actions/previewmodeR-on.png differ diff --git a/rtdata/images/Light/actions/HDR-thumbnail.png b/rtdata/images/Light/actions/HDR-thumbnail.png new file mode 100644 index 000000000..182e603e8 Binary files /dev/null and b/rtdata/images/Light/actions/HDR-thumbnail.png differ diff --git a/rtdata/images/Light/actions/PixelShift-thumbnail.png b/rtdata/images/Light/actions/PixelShift-thumbnail.png new file mode 100644 index 000000000..4bbea1aee Binary files /dev/null and b/rtdata/images/Light/actions/PixelShift-thumbnail.png differ diff --git a/rtdata/images/Light/actions/previewmodeB-off.png b/rtdata/images/Light/actions/previewmodeB-off.png index 1ff087b4d..0c9890437 100644 Binary files a/rtdata/images/Light/actions/previewmodeB-off.png and b/rtdata/images/Light/actions/previewmodeB-off.png differ diff --git a/rtdata/images/Light/actions/previewmodeB-on.png b/rtdata/images/Light/actions/previewmodeB-on.png index 6403fc722..466192b3a 100644 Binary files a/rtdata/images/Light/actions/previewmodeB-on.png and b/rtdata/images/Light/actions/previewmodeB-on.png differ diff --git a/rtdata/images/Light/actions/previewmodeBC0-off.png b/rtdata/images/Light/actions/previewmodeBC0-off.png index 05a75ee25..28c024555 100644 Binary files a/rtdata/images/Light/actions/previewmodeBC0-off.png and b/rtdata/images/Light/actions/previewmodeBC0-off.png differ diff --git a/rtdata/images/Light/actions/previewmodeBC0-on.png b/rtdata/images/Light/actions/previewmodeBC0-on.png index a1f462cb2..f5e0b8000 100644 Binary files a/rtdata/images/Light/actions/previewmodeBC0-on.png and b/rtdata/images/Light/actions/previewmodeBC0-on.png differ diff --git a/rtdata/images/Light/actions/previewmodeBC1-off.png b/rtdata/images/Light/actions/previewmodeBC1-off.png index d5071108a..4ac160b05 100644 Binary files a/rtdata/images/Light/actions/previewmodeBC1-off.png and b/rtdata/images/Light/actions/previewmodeBC1-off.png differ diff --git a/rtdata/images/Light/actions/previewmodeBC1-on.png b/rtdata/images/Light/actions/previewmodeBC1-on.png index f71b27965..3e9b6874c 100644 Binary files a/rtdata/images/Light/actions/previewmodeBC1-on.png and b/rtdata/images/Light/actions/previewmodeBC1-on.png differ diff --git a/rtdata/images/Light/actions/previewmodeBC2-off.png b/rtdata/images/Light/actions/previewmodeBC2-off.png index 5c9b2d0e8..bf3d97b2d 100644 Binary files a/rtdata/images/Light/actions/previewmodeBC2-off.png and b/rtdata/images/Light/actions/previewmodeBC2-off.png differ diff --git a/rtdata/images/Light/actions/previewmodeBC2-on.png b/rtdata/images/Light/actions/previewmodeBC2-on.png index 8f5b9207e..457453166 100644 Binary files a/rtdata/images/Light/actions/previewmodeBC2-on.png and b/rtdata/images/Light/actions/previewmodeBC2-on.png differ diff --git a/rtdata/images/Light/actions/previewmodeBC3-off.png b/rtdata/images/Light/actions/previewmodeBC3-off.png new file mode 100644 index 000000000..487ec777e Binary files /dev/null and b/rtdata/images/Light/actions/previewmodeBC3-off.png differ diff --git a/rtdata/images/Light/actions/previewmodeBC3-on.png b/rtdata/images/Light/actions/previewmodeBC3-on.png new file mode 100644 index 000000000..670b5b8b4 Binary files /dev/null and b/rtdata/images/Light/actions/previewmodeBC3-on.png differ diff --git a/rtdata/images/Light/actions/previewmodeF-focusScreen-off.png b/rtdata/images/Light/actions/previewmodeF-focusScreen-off.png new file mode 100644 index 000000000..0aa81a705 Binary files /dev/null and b/rtdata/images/Light/actions/previewmodeF-focusScreen-off.png differ diff --git a/rtdata/images/Light/actions/previewmodeF-focusScreen-on.png b/rtdata/images/Light/actions/previewmodeF-focusScreen-on.png new file mode 100644 index 000000000..3d46dedc7 Binary files /dev/null and b/rtdata/images/Light/actions/previewmodeF-focusScreen-on.png differ diff --git a/rtdata/images/Light/actions/previewmodeF-off.png b/rtdata/images/Light/actions/previewmodeF-off.png index 519de02bc..5d52af569 100644 Binary files a/rtdata/images/Light/actions/previewmodeF-off.png and b/rtdata/images/Light/actions/previewmodeF-off.png differ diff --git a/rtdata/images/Light/actions/previewmodeF-on.png b/rtdata/images/Light/actions/previewmodeF-on.png index 3910e6a20..f0d0ef230 100644 Binary files a/rtdata/images/Light/actions/previewmodeF-on.png and b/rtdata/images/Light/actions/previewmodeF-on.png differ diff --git a/rtdata/images/Light/actions/previewmodeG-off.png b/rtdata/images/Light/actions/previewmodeG-off.png index e25911324..5c076c989 100644 Binary files a/rtdata/images/Light/actions/previewmodeG-off.png and b/rtdata/images/Light/actions/previewmodeG-off.png differ diff --git a/rtdata/images/Light/actions/previewmodeG-on.png b/rtdata/images/Light/actions/previewmodeG-on.png index db31667ed..ecc75c8e7 100644 Binary files a/rtdata/images/Light/actions/previewmodeG-on.png and b/rtdata/images/Light/actions/previewmodeG-on.png differ diff --git a/rtdata/images/Light/actions/previewmodeL-off.png b/rtdata/images/Light/actions/previewmodeL-off.png index d24dea76f..939dec642 100644 Binary files a/rtdata/images/Light/actions/previewmodeL-off.png and b/rtdata/images/Light/actions/previewmodeL-off.png differ diff --git a/rtdata/images/Light/actions/previewmodeL-on.png b/rtdata/images/Light/actions/previewmodeL-on.png index 11b745e09..92fe937e8 100644 Binary files a/rtdata/images/Light/actions/previewmodeL-on.png and b/rtdata/images/Light/actions/previewmodeL-on.png differ diff --git a/rtdata/images/Light/actions/previewmodeR-off.png b/rtdata/images/Light/actions/previewmodeR-off.png index 9aef77301..b96e22c31 100644 Binary files a/rtdata/images/Light/actions/previewmodeR-off.png and b/rtdata/images/Light/actions/previewmodeR-off.png differ diff --git a/rtdata/images/Light/actions/previewmodeR-on.png b/rtdata/images/Light/actions/previewmodeR-on.png index 5fb0f996e..fb1e46e98 100644 Binary files a/rtdata/images/Light/actions/previewmodeR-on.png and b/rtdata/images/Light/actions/previewmodeR-on.png differ diff --git a/rtdata/images/rt_splash.svg b/rtdata/images/rt_splash.svg index 8048ccb97..c80cdd5c7 100644 --- a/rtdata/images/rt_splash.svg +++ b/rtdata/images/rt_splash.svg @@ -10,20 +10,48 @@ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="588.79999" - height="369.06668" - id="svg2" + width="552" + height="346" + viewBox="0 0 146.05 91.545836" version="1.1" + id="svg783" inkscape:version="0.92.1 r" sodipodi:docname="rt_splash.svg" - style="enable-background:new" - inkscape:export-filename="/tmp/rt_splash_52_dev.png" - inkscape:export-xdpi="90" - inkscape:export-ydpi="90"> - RawTherapee Splash Screen + inkscape:export-filename="/tmp/splash.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96"> + id="defs777"> + + + + + + + @@ -58,6 +106,16 @@ offset="1" style="stop-color:#971ec6;stop-opacity:1" /> + + @@ -81,6 +149,16 @@ offset="1" style="stop-color:#1526c3;stop-opacity:1" /> + + @@ -104,6 +192,16 @@ offset="1" style="stop-color:#fc12aa;stop-opacity:1" /> + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + inkscape:window-maximized="1"> + inkscape:color="rgb(0,0,255)" /> - - - + + + - - + id="metadata780"> image/svg+xml - RawTherapee Splash Screen - - - Morgan Hardwood - - - - - rawtherapee - logo - splash - - - www.rawtherapee.com - + - - - - - - - - + transform="translate(0,-205.45415)"> + style="fill:#2a2a2a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.26458338;enable-background:new" /> + width="146.05" + height="32.22514" + x="0" + y="310.22934" + rx="3.1236236" + ry="1.1284066" /> + transform="matrix(0.6837777,0,0,0.68377778,2.6015099,222.16553)" + style="filter:url(#filter3580);enable-background:new">  For logo specifics, refer to rt_logo.svg 64pt, skewed -3°. RawTherapee splash screen design version 1.1 from 2017-01-28 | www.rawtherapee.com -     + x="32.400429" + y="340.74057" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:1.60844219px;line-height:1.25;font-family:OxygenSans;-inkscape-font-specification:OxygenSans;letter-spacing:0.26807371px;fill:#ffcc00;fill-opacity:1;stroke-width:0.26807371">RawTherapee splash screen design version 1.1 from 2017-01-28 | www.rawtherapee.com Raw Therapee GNU GPLv3 + x="7.6874547" + y="290.34174" + style="font-size:3.96875px;line-height:1.25;stroke-width:0.26458338px">GNU GPLv3 5 . 2 + sodipodi:role="line">. 3 + transform="matrix(0.24804687,0,0,0.2480469,-10.282719,273.1232)" + style="fill:#ffffff;enable-background:new"> Development - diff --git a/rtdata/images/splash.png b/rtdata/images/splash.png index 2a0806946..701ef02bf 100644 Binary files a/rtdata/images/splash.png and b/rtdata/images/splash.png differ diff --git a/rtdata/languages/Catala b/rtdata/languages/Catala index ff700b720..eda2ad2ad 100644 --- a/rtdata/languages/Catala +++ b/rtdata/languages/Catala @@ -512,7 +512,6 @@ PREFERENCES_CUSTPROFBUILD;Constructor de perfils de procés particulars PREFERENCES_CUSTPROFBUILDHINT;Nom del fitxer executable (o script) per a usar un nou perfil de procés en una imatge.\nRep paràmetres en línia d'ordres per a la generació de perfils basats en regles:\n[raw/JPG path] [path per omissió del perfil de procés] [número f] [expos. en segons] [long. focal en mm] [ISO] [objectiu] [càmera] PREFERENCES_CUSTPROFBUILDPATH;Executable path PREFERENCES_CUTOVERLAYBRUSH;Cropa màscara color/transparència -PREFERENCES_DARKFRAME;Marc fosc PREFERENCES_DARKFRAMEFOUND;Trobat PREFERENCES_DARKFRAMESHOTS;trets PREFERENCES_DARKFRAMETEMPLATES;plantilles @@ -530,7 +529,6 @@ PREFERENCES_EXTERNALEDITOR;Editor extern PREFERENCES_FBROWSEROPTS;Opcions de navegador i minifotos PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Barra de gestor de fitxers d'una línia (inapropiat en monitors de baixa resolució) PREFERENCES_FILEFORMAT;Format de fitxer -PREFERENCES_FLATFIELD;Camp pla PREFERENCES_FLATFIELDFOUND;Trobat PREFERENCES_FLATFIELDSDIR;Carpeta de camps plans PREFERENCES_FLATFIELDSHOTS;trets @@ -976,6 +974,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !DYNPROFILEEDITOR_PROFILE;Processing Profile !EDIT_OBJECT_TOOLTIP;Displays a widget on the preview window which lets you adjust this tool. !EDIT_PIPETTE_TOOLTIP;To add an adjustment point to the curve, hold the Ctrl key while left-clicking the desired spot in the image preview.\nTo adjust the point, hold the Ctrl key while left-clicking the corresponding area in the preview, then let go of Ctrl (unless you desire fine control) and while still holding the left mouse button move the mouse up or down to move that point up or down in the curve. +!EXIFPANEL_SHOWALL;Show all !EXPORT_BYPASS;Processing steps to bypass !EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels !EXPORT_BYPASS_RAW_LMMSE_ITERATIONS;Bypass [raw] LMMSE Enhancement Steps @@ -1314,6 +1313,12 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !HISTORY_MSG_482;CAM02 - Green scene !HISTORY_MSG_483;CAM02 - Yb scene !HISTORY_MSG_484;CAM02 - Auto Yb scene +!HISTORY_MSG_485;Lens Correction +!HISTORY_MSG_486;Lens Correction - Camera +!HISTORY_MSG_487;Lens Correction - Lens +!HISTORY_MSG_488;HDR Tone Mapping +!HISTORY_MSG_489;HDR TM - Threshold +!HISTORY_MSG_490;HDR TM - Amount !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider. !IPTCPANEL_CITYHINT;Enter the name of the city pictured in this image. @@ -1340,6 +1345,10 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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. +!LENSPROFILE_CORRECTION_AUTOMATCH;Auto-matched correction parameters +!LENSPROFILE_CORRECTION_LCPFILE;LCP File +!LENSPROFILE_CORRECTION_MANUAL;Manual correction parameters +!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. !MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the next image relative to image opened in the Editor.\nShortcut: Shift-F4\n\nTo navigate to the next image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F4 !MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the previous image relative to image opened in the Editor.\nShortcut: Shift-F3\n\nTo navigate to the previous image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F3 !MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchronize the File Browser or Filmstrip with the Editor to reveal the thumbnail of the currently opened image, and clear any active filters.\nShortcut: x\n\nAs above, but without clearing active filters:\nShortcut: y\n(Note that the thumbnail of the opened image will not be shown if filtered out). @@ -1352,6 +1361,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !MAIN_TAB_INSPECT; Inspect !MAIN_TAB_WAVELET;Wavelet !MAIN_TAB_WAVELET_TOOLTIP;Shortcut: Alt-w +!MAIN_TOOLTIP_BACKCOLOR3;Background color of the preview: Middle grey\nShortcut: 9 !MONITOR_PROFILE_SYSTEM;System default !NAVIGATOR_B;B: !NAVIGATOR_G;G: @@ -1377,14 +1387,16 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !PARTIALPASTE_RAWCACORR_CAREDBLUE;CA red & blue !PARTIALPASTE_RAW_IMAGENUM;Sub-image !PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps -!PARTIALPASTE_RAW_PIXELSHIFT;PixelShift +!PARTIALPASTE_RAW_PIXELSHIFT;Pixel Shift !PARTIALPASTE_RETINEX;Retinex +!PARTIALPASTE_TM_FATTAL;HDR Tone mapping !PARTIALPASTE_WAVELETGROUP;Wavelet Levels !PREFERENCES_AUTLISLOW;Low !PREFERENCES_AUTLISMAX;Max - Average of all tiles !PREFERENCES_AUTLISSTD;High !PREFERENCES_AUTLISVLOW;None !PREFERENCES_AUTLOW;Low +!PREFERENCES_AUTOSAVE_TP_OPEN;Automatically save tools collapsed/expanded\nstate before exiting !PREFERENCES_AUTSTD;Standard !PREFERENCES_BEHADDALL;All to 'Add' !PREFERENCES_BEHADDALLHINT;Set all parameters to the Add mode.\nAdjustments of parameters in the batch tool panel will be deltas to the stored values. @@ -1414,8 +1426,8 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !PREFERENCES_D65;6500K !PREFERENCES_DAUB_LABEL;Use Daubechies D6 wavelets instead of D4 !PREFERENCES_DAUB_TOOLTIP;The Noise Reduction and Wavelet Levels tools use a Debauchies mother wavelet. If you choose D6 instead of D4 you increase the number of orthogonal Daubechies coefficients and probably increase quality of small-scale levels. There is no memory or processing time difference between the two. +!PREFERENCES_DIRECTORIES;Directories !PREFERENCES_EXPAUT;Expert -!PREFERENCES_FILMSIMULATION;Film Simulation !PREFERENCES_FLUOF2;Fluorescent F2 !PREFERENCES_FLUOF7;Fluorescent F7 !PREFERENCES_FLUOF11;Fluorescent F11 @@ -1471,6 +1483,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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_RGBDTL_LABEL;Max number of threads for Noise Reduction and Wavelet Levels !PREFERENCES_RGBDTL_TOOLTIP;Leave the setting at "0" to automatically use as many threads as possible. The more threads run in parallel, the faster the computation. Refer to RawPedia for memory requirements. +!PREFERENCES_SAVE_TP_OPEN_NOW;Save tools collapsed/expanded state now !PREFERENCES_SELECTFONT_COLPICKER;Select Color Picker's font !PREFERENCES_SERIALIZE_TIFF_READ;Tiff Read Settings !PREFERENCES_SERIALIZE_TIFF_READ_LABEL;Serialize read of tiff files @@ -1499,10 +1512,19 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !PROFILEPANEL_PINTERNAL;Neutral !PROGRESSBAR_NOIMAGES;No images found !PROGRESSBAR_SNAPSHOT_ADDED;Snapshot added +!QINFO_FRAMECOUNT;%2 frames +!QINFO_HDR;HDR / %2 frame(s) +!QINFO_PIXELSHIFT;Pixel Shift / %2 frame(s) +!SAMPLEFORMAT_0;Unknown data format +!SAMPLEFORMAT_1;Unsigned 8 bits +!SAMPLEFORMAT_2;Unsigned 16 bits +!SAMPLEFORMAT_4;LogLuv 24 bits +!SAMPLEFORMAT_8;LogLuv 32 bits +!SAMPLEFORMAT_16;32 bits floating point !SAVEDLG_FORCEFORMATOPTS;Force saving options !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;If active, indicates in grey the pixels which have out of gamut colors from the output profile. -!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate de rendering generated by the output profile of the ICM tool. Most useful for simulating printing outputs. +!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the Printer profile. +!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate the printer's output by using the Printer profile set in Preferences > Color Management. !TOOLBAR_TOOLTIP_COLORPICKER;Lockable Color Picker\n\nWhen enabled:\nClick in the preview with left mouse button to add a color picker\nDrag it around while pressing the left mouse button\nDelete the color picker with a right mouse button click\nDelete all color pickers with Shift + Right mouse button click\nRight click away from any color picker to go back to the Hand tool !TP_BWMIX_ALGO;Algorithm OYCPM !TP_BWMIX_ALGO_LI;Linear @@ -1639,7 +1661,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !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 Tint=1.\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\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504 !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_WBCAM;WB [RT+CAT02] + [output] @@ -1981,6 +2003,9 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_RGBCURVES_LUMAMODE_TOOLTIP;Luminosity mode allows to vary the contribution of R, G and B channels to the luminosity of the image, without altering image color. !TP_SAVEDIALOG_OK_TIP;Shortcut: Ctrl-Enter !TP_SHADOWSHLIGHTS_SHARPMASK;Sharp mask +!TP_TM_FATTAL_AMOUNT;Amount +!TP_TM_FATTAL_LABEL;HDR Tone Mapping +!TP_TM_FATTAL_THRESHOLD;Threshold !TP_WAVELET_1;Level 1 !TP_WAVELET_2;Level 2 !TP_WAVELET_3;Level 3 diff --git a/rtdata/languages/Chinese (Simplified) b/rtdata/languages/Chinese (Simplified) index 2fd87fe5e..51aed581d 100644 --- a/rtdata/languages/Chinese (Simplified) +++ b/rtdata/languages/Chinese (Simplified) @@ -3,12 +3,13 @@ #02 2008-11-06 Yang Gao (grantyale) #03 2013-10-20 Jiero #04 2014-10-24 Jie Luo +#05 2017-09-18 Chongnuo Ji ABOUT_TAB_BUILD;版本 ABOUT_TAB_CREDITS;感谢 ABOUT_TAB_LICENSE;授权协议 ABOUT_TAB_RELEASENOTES;发布说明 -ABOUT_TAB_SPLASH;Splash +ABOUT_TAB_SPLASH;启动页 ADJUSTER_RESET_TO_DEFAULT;重置缺省参数 BATCHQUEUE_AUTOSTART;自动开始 BATCHQUEUE_DESTFILENAME;路径和文件名 @@ -21,20 +22,37 @@ CURVEEDITOR_HIGHLIGHTS;高亮 CURVEEDITOR_LIGHTS;光 CURVEEDITOR_LINEAR;线性 CURVEEDITOR_LOADDLGLABEL;正读取曲线... +CURVEEDITOR_MINMAXCPOINTS;均衡器 +CURVEEDITOR_NURBS;控制点 +CURVEEDITOR_PARAMETRIC;参数 CURVEEDITOR_SAVEDLGLABEL;正保存曲线... CURVEEDITOR_SHADOWS;阴影 +CURVEEDITOR_TOOLTIPCOPY;复制当前曲线到剪贴板 CURVEEDITOR_TOOLTIPLINEAR;重置曲线 CURVEEDITOR_TOOLTIPLOAD;读取曲线 +CURVEEDITOR_TOOLTIPPASTE;从剪贴板粘贴曲线 CURVEEDITOR_TOOLTIPSAVE;保存曲线 CURVEEDITOR_TYPE;类型: DIRBROWSER_FOLDERS;文件夹 +DONT_SHOW_AGAIN;不再显示该信息 +DYNPROFILEEDITOR_DELETE;删除 +DYNPROFILEEDITOR_EDIT;编辑 +DYNPROFILEEDITOR_EDIT_RULE;编辑动态配置规则 +DYNPROFILEEDITOR_ENTRY_TOOLTIP;该项匹配不区分大小写 \n使用 "re:" 前缀来输入 \na 正则式 +DYNPROFILEEDITOR_MOVE_DOWN;下移 +DYNPROFILEEDITOR_MOVE_UP;上移 +DYNPROFILEEDITOR_NEW;新建 +DYNPROFILEEDITOR_NEW_RULE;新建动态配置规则 +DYNPROFILEEDITOR_PROFILE;处理配置规则 EDITWINDOW_TITLE;图片修改 EXIFFILTER_APERTURE;光圈 EXIFFILTER_CAMERA;相机 +EXIFFILTER_EXPOSURECOMPENSATION;曝光补偿值 (EV) EXIFFILTER_FILETYPE;文件类型 EXIFFILTER_FOCALLEN;焦距 EXIFFILTER_ISO;感光度 EXIFFILTER_LENS;镜头 +EXIFFILTER_METADATAFILTER;启用元数据过滤器 EXIFFILTER_SHUTTER;快门 EXIFPANEL_ADDEDIT;添加/编辑 EXIFPANEL_ADDEDITHINT;添加/编辑标签 @@ -51,31 +69,60 @@ EXIFPANEL_RESETALLHINT;重置所有标签内容 EXIFPANEL_RESETHINT;重置所选标签内容 EXIFPANEL_SUBDIRECTORY;子文件夹 EXPORT_BYPASS_ALL;(取消)选择全部 -EXPORT_BYPASS_RAW_FF;Bypass [raw] 平场 -EXPORT_BYPASS_RAW_LINENOISE;Bypass [raw] 线噪过滤 +EXPORT_BYPASS_DEFRINGE;不应用去边处理 +EXPORT_BYPASS_DIRPYRDENOISE;不应用降噪处理 +EXPORT_BYPASS_DIRPYREQUALIZER;不应用分频反差调整 +EXPORT_BYPASS_EQUALIZER;不应用小波变换级别处理 +EXPORT_BYPASS_RAW_CA;不应用 [raw] 色差矫正 +EXPORT_BYPASS_RAW_CCSTEPS;不应用 [raw] 摩尔纹控制 +EXPORT_BYPASS_RAW_DF;不应用 [raw] 暗场处理 +EXPORT_BYPASS_RAW_FF;不应用 [raw] 平场 +EXPORT_BYPASS_RAW_GREENTHRESH;不应用 [raw] 绿色偏纠正 +EXPORT_BYPASS_RAW_LINENOISE;不应用 [raw] 线噪过滤 +EXPORT_BYPASS_SHARPENEDGE;不应用边缘锐化 +EXPORT_BYPASS_SHARPENING;不应用锐化 +EXPORT_BYPASS_SHARPENMICRO;不应用微反差调节 EXPORT_FASTEXPORTOPTIONS;快速导出选项 EXPORT_MAXHEIGHT;最大高度 EXPORT_MAXWIDTH;最大宽度 EXPORT_PUTTOQUEUEFAST; 放入快速导出序列 +EXPORT_RAW_DMETHOD;反拜尔算法 EXTPROGTARGET_1;raw +EXTPROGTARGET_2;队列已处理 +FILEBROWSER_ADDDELTEMPLATE;增加/删除模板... FILEBROWSER_APPLYPROFILE;应用配置 +FILEBROWSER_APPLYPROFILE_PARTIAL;应用 - 局部 +FILEBROWSER_AUTODARKFRAME;自动暗场 +FILEBROWSER_AUTOFLATFIELD;自动平场 +FILEBROWSER_BROWSEPATHBUTTONHINT;点击浏览选择的路径 FILEBROWSER_CACHE;缓存 FILEBROWSER_CACHECLEARFROMFULL;清空缓存 FILEBROWSER_CACHECLEARFROMPARTIAL;清理缓存 FILEBROWSER_CLEARPROFILE;清空配置 FILEBROWSER_COPYPROFILE;复制配置 FILEBROWSER_CURRENT_NAME;当前名称: +FILEBROWSER_DARKFRAME;暗场 FILEBROWSER_DELETEDLGLABEL;确认删除 FILEBROWSER_DELETEDLGMSG;确定删除所选的%1个文件? +FILEBROWSER_DELETEDLGMSGINCLPROC;你确认要删除选择的 %1 文件 包括 一个处理队列中的版本? FILEBROWSER_EMPTYTRASH;清空垃圾箱 FILEBROWSER_EMPTYTRASHHINT;永久清空垃圾箱 FILEBROWSER_EXTPROGMENU;调用程序... +FILEBROWSER_FLATFIELD;平场 +FILEBROWSER_MOVETODARKFDIR;移动到暗场路径 +FILEBROWSER_MOVETOFLATFIELDDIR;移动到平场路径 FILEBROWSER_NEW_NAME;新名称: FILEBROWSER_OPENDEFAULTVIEWER;Windows 默认阅览工具 (序列) FILEBROWSER_PARTIALPASTEPROFILE;选择性粘贴 FILEBROWSER_PASTEPROFILE;粘贴配置 FILEBROWSER_POPUPCANCELJOB;取消任务 FILEBROWSER_POPUPCOLORLABEL;彩色标帖 +FILEBROWSER_POPUPCOLORLABEL0;Label: 无 +FILEBROWSER_POPUPCOLORLABEL1;Label: 红 +FILEBROWSER_POPUPCOLORLABEL2;Label: 黄 +FILEBROWSER_POPUPCOLORLABEL3;Label: 绿 +FILEBROWSER_POPUPCOLORLABEL4;Label: 蓝 +FILEBROWSER_POPUPCOLORLABEL5;Label: 紫 FILEBROWSER_POPUPCOPYTO;复制至... FILEBROWSER_POPUPFILEOPERATIONS;文件操作 FILEBROWSER_POPUPMOVEEND;移动到队列尾部 @@ -86,6 +133,8 @@ FILEBROWSER_POPUPOPENINEDITOR;打开在编辑器 FILEBROWSER_POPUPPROCESS;放入队列 FILEBROWSER_POPUPPROCESSFAST;放入序列(快速导出) FILEBROWSER_POPUPPROFILEOPERATIONS;处理色彩档案 +FILEBROWSER_POPUPRANK;评分 +FILEBROWSER_POPUPRANK0;去评分 FILEBROWSER_POPUPRANK1;评 1 星 FILEBROWSER_POPUPRANK2;评 2 星 FILEBROWSER_POPUPRANK3;评 3 星 @@ -100,16 +149,17 @@ FILEBROWSER_POPUPUNRANK;取消星级 FILEBROWSER_POPUPUNTRASH;从垃圾箱中移除 FILEBROWSER_QUERYBUTTONHINT;清除搜索序列 FILEBROWSER_QUERYLABEL; 查找: -FILEBROWSER_RANK1_TOOLTIP;Rank 1 *\nShortcut: Shift-1 -FILEBROWSER_RANK2_TOOLTIP;Rank 2 *\nShortcut: Shift-2 -FILEBROWSER_RANK3_TOOLTIP;Rank 3 *\nShortcut: Shift-3 -FILEBROWSER_RANK4_TOOLTIP;Rank 4 *\nShortcut: Shift-4 -FILEBROWSER_RANK5_TOOLTIP;Rank 5 *\nShortcut: Shift-5 +FILEBROWSER_RANK1_TOOLTIP;评分 1 *\n快捷键:Shift-1 +FILEBROWSER_RANK2_TOOLTIP;评分 2 *\n快捷键:Shift-2 +FILEBROWSER_RANK3_TOOLTIP;评分 3 *\n快捷键:Shift-3 +FILEBROWSER_RANK4_TOOLTIP;评分 4 *\n快捷键:Shift-4 +FILEBROWSER_RANK5_TOOLTIP;评分 5 *\n快捷键:Shift-5 FILEBROWSER_RENAMEDLGLABEL;文件重命名 -FILEBROWSER_SELECTDARKFRAME;选择暗幅... +FILEBROWSER_RESETDEFAULTPROFILE;还原到默认 +FILEBROWSER_SELECTDARKFRAME;选择暗场... FILEBROWSER_SELECTFLATFIELD;选择平场…… FILEBROWSER_SHOWDIRHINT;显示文件夹中所有图片 -FILEBROWSER_SHOWEXIFINFO;显示Exif 信息\n\n快捷:\ni - 多编辑标签页模式,\nAlt-i - 单编辑标签模式 +FILEBROWSER_SHOWEXIFINFO;显示Exif 信息\n\n快捷:\ni - 多编辑标签页模式, \nAlt-i - 单编辑标签模式 FILEBROWSER_SHOWRANK1HINT;显示1星图片 FILEBROWSER_SHOWRANK2HINT;显示2星图片 FILEBROWSER_SHOWRANK3HINT;显示3星图片 @@ -125,8 +175,17 @@ FILEBROWSER_STOPPROCESSINGHINT;停止处理图片 FILEBROWSER_THUMBSIZE;缩略图大小 FILEBROWSER_ZOOMINHINT;增大缩略图 FILEBROWSER_ZOOMOUTHINT;减小缩略图 +FILECHOOSER_FILTER_ANY;所有文件 +FILECHOOSER_FILTER_COLPROF;色彩配置文件 +FILECHOOSER_FILTER_CURVE;曲线文件 +FILECHOOSER_FILTER_LCP;镜头矫正配置文件 +FILECHOOSER_FILTER_PP;处理预设文件 +FILECHOOSER_FILTER_SAME;与当前照片格式相同 +FILECHOOSER_FILTER_TIFF;TIFF 文件 GENERAL_ABOUT;关于 GENERAL_AFTER;之后 +GENERAL_APPLY;应用 +GENERAL_ASIMAGE;跟随图像 GENERAL_AUTO;自动 GENERAL_BEFORE;之前 GENERAL_CANCEL;取消 @@ -141,6 +200,7 @@ GENERAL_NA;不适用 GENERAL_NO;否 GENERAL_NONE;无 GENERAL_OK;确定 +GENERAL_OPEN;打开 GENERAL_PORTRAIT;纵向 GENERAL_SAVE;保存 GENERAL_UNCHANGED;(未改变) @@ -159,7 +219,7 @@ HISTORY_MSG_3;配置改变 HISTORY_MSG_4;历史浏览 HISTORY_MSG_5;亮度 HISTORY_MSG_6;对比度 -HISTORY_MSG_7;黑 +HISTORY_MSG_7;黑点 HISTORY_MSG_8;曝光补偿 HISTORY_MSG_9;高光压缩 HISTORY_MSG_10;阴影压缩 @@ -223,14 +283,14 @@ HISTORY_MSG_67;高光还原程度 HISTORY_MSG_68;高光还原方式 HISTORY_MSG_69;工作色彩空间 HISTORY_MSG_70;输出色彩空间 -HISTORY_MSG_71;输入色参空间 +HISTORY_MSG_71;输入色彩空间 HISTORY_MSG_72;暗角矫正 HISTORY_MSG_73;通道混合器 HISTORY_MSG_74;调整大小比例 HISTORY_MSG_75;调整大小方式 HISTORY_MSG_76;Exif元数据 HISTORY_MSG_77;IPTC元数据 -HISTORY_MSG_78;Data specified for resize +HISTORY_MSG_78;调整大小数据 HISTORY_MSG_79;调整宽度 HISTORY_MSG_80;调整高度 HISTORY_MSG_81;调整尺寸开启 @@ -259,7 +319,7 @@ HISTORY_MSG_155;Vib - 避免色彩偏移 HISTORY_MSG_158;力度 HISTORY_MSG_159;边缘停止 HISTORY_MSG_160;拉伸 -HISTORY_MSG_162;色阶映射 +HISTORY_MSG_162;色调映射 HISTORY_MSG_173;降噪 - 亮度细节 HISTORY_MSG_174;CIECAM02 HISTORY_MSG_183;CAM02 - 对比度 (J) @@ -279,7 +339,7 @@ IPTCPANEL_CITY;城市 IPTCPANEL_COPYHINT;将IPTC设置复制到剪贴板 IPTCPANEL_COUNTRY;国家 IPTCPANEL_CREDIT;提供者 -IPTCPANEL_CREDITHINT;图片提供者,未必是作者 +IPTCPANEL_CREDITHINT;图片提供者, 未必是作者 IPTCPANEL_DATECREATED;创作日期 IPTCPANEL_EMBEDDED;内嵌 IPTCPANEL_EMBEDDEDHINT;将IPTC数据重置为图片内嵌数据 @@ -295,12 +355,12 @@ MAIN_BUTTON_FULLSCREEN;全屏幕 MAIN_BUTTON_PREFERENCES;参数设置 MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;将当前图片放入处理序列中\n快捷键: Ctrl+b MAIN_BUTTON_SAVE;保存图片 -MAIN_BUTTON_SAVE_TOOLTIP;保存当前图像。\n快捷键:Ctrl+S +MAIN_BUTTON_SAVE_TOOLTIP;保存当前图像 \n快捷键:Ctrl+S MAIN_BUTTON_SENDTOEDITOR;发送到编辑器 -MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;使用外部工具编辑当前图像。\n快捷键:Ctrl+E +MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;使用外部工具编辑当前图像 \n快捷键:Ctrl+E MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;显示/隐藏全部侧边栏\n快捷键: m MAIN_BUTTON_UNFULLSCREEN;退出全屏 -MAIN_FRAME_BATCHQUEUE;批量处理序列 +MAIN_FRAME_BATCHQUEUE;批处理队列 MAIN_FRAME_BATCHQUEUE_TOOLTIP;处理序列\n快捷键: Ctrl-F3 MAIN_FRAME_EDITOR;编辑器 MAIN_FRAME_EDITOR_TOOLTIP;编辑器.\n快捷键: Ctrl-F4 @@ -314,33 +374,41 @@ MAIN_MSG_ALREADYEXISTS;该文件已存在 MAIN_MSG_CANNOTLOAD;无法加载图片 MAIN_MSG_CANNOTSAVE;文件保存中出错 MAIN_MSG_CANNOTSTARTEDITOR;无法启动编辑器 -MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;请在“首选项“对话框设置正确的路径。 +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;请在“首选项“对话框设置正确的路径 MAIN_MSG_EMPTYFILENAME;未指定文件名! MAIN_MSG_NAVIGATOR;浏览器 MAIN_MSG_OPERATIONCANCELLED;取消 MAIN_MSG_QOVERWRITE;是否覆盖? MAIN_TAB_COLOR;色彩 -MAIN_TAB_DETAIL;详细 -MAIN_TAB_DEVELOP;图片开发 +MAIN_TAB_COLOR_TOOLTIP;快捷键:Alt-c +MAIN_TAB_DETAIL;细节 +MAIN_TAB_DETAIL_TOOLTIP;快捷键: Alt-d +MAIN_TAB_DEVELOP;图片调整 MAIN_TAB_EXIF;Exif MAIN_TAB_EXPORT; 快速导出 MAIN_TAB_EXPOSURE;曝光 -MAIN_TAB_FILTER;滤镜 +MAIN_TAB_EXPOSURE_TOOLTIP;快捷键:Alt-e +MAIN_TAB_FILTER;过滤器 +MAIN_TAB_INSPECT; 检阅 MAIN_TAB_IPTC;IPTC MAIN_TAB_METADATA;元数据 +MAIN_TAB_METADATA_TOOLTIP;快捷键:Alt-m MAIN_TAB_RAW;Raw MAIN_TAB_RAW_TOOLTIP;快捷键:Alt-R -MAIN_TAB_TRANSFORM;转换 +MAIN_TAB_TRANSFORM;变换 +MAIN_TAB_TRANSFORM_TOOLTIP;快捷键:Alt-t +MAIN_TAB_WAVELET;小波变换 +MAIN_TAB_WAVELET_TOOLTIP;快捷键:Alt-w MAIN_TOOLTIP_HIDEHP;显示/隐藏左面板 (包含历史, 快捷键: H) MAIN_TOOLTIP_INDCLIPPEDH;高光溢出提示 MAIN_TOOLTIP_INDCLIPPEDS;阴影不足提示 -MAIN_TOOLTIP_PREVIEWR;Preview the Red channel.\nShortcut: r +MAIN_TOOLTIP_PREVIEWR;预览 红色通道.\n快捷键: r MAIN_TOOLTIP_QINFO;图片快捷信息 MAIN_TOOLTIP_SHOWHIDELP1;显示/隐藏左面板\n快捷键: l MAIN_TOOLTIP_SHOWHIDERP1;显示/隐藏右面板\n快捷键: Alt-l MAIN_TOOLTIP_SHOWHIDETP1;显示/隐藏上面板\n快捷键: Shift-L -MAIN_TOOLTIP_THRESHOLD;阀值 -MAIN_TOOLTIP_TOGGLE;Toggle the /视图\nShortcut: Shift-b +MAIN_TOOLTIP_THRESHOLD;阈值 +MAIN_TOOLTIP_TOGGLE;切换 /视图\n快捷键: Shift-b NAVIGATOR_B;B: NAVIGATOR_G;G: NAVIGATOR_H;H: @@ -354,28 +422,39 @@ NAVIGATOR_V;V: NAVIGATOR_XY_FULL;宽 = %1, 高 = %2 NAVIGATOR_XY_NA;x = n/a, y = n/a PARTIALPASTE_BASICGROUP;基本设置 -PARTIALPASTE_CACORRECTION;色彩校正 +PARTIALPASTE_CACORRECTION;色彩矫正 PARTIALPASTE_CHANNELMIXER;通道混合器 PARTIALPASTE_CHANNELMIXERBW;黑白 PARTIALPASTE_COARSETRANS;90度旋转/翻转 -PARTIALPASTE_COLORAPP;CIECAM02 国际照明协会色彩显示框架2002 +PARTIALPASTE_COLORAPP;CIECAM02 PARTIALPASTE_COLORGROUP;色彩相关设定 +PARTIALPASTE_COLORTONING;色调 PARTIALPASTE_COMMONTRANSFORMPARAMS;自动填充 PARTIALPASTE_COMPOSITIONGROUP;构图设置 PARTIALPASTE_CROP;剪裁 -PARTIALPASTE_DARKFRAMEAUTOSELECT;暗幅自动选择 -PARTIALPASTE_DARKFRAMEFILE;暗幅文件 +PARTIALPASTE_DARKFRAMEAUTOSELECT;暗场自动选择 +PARTIALPASTE_DARKFRAMEFILE;暗场文件 +PARTIALPASTE_DEFRINGE;去边 PARTIALPASTE_DETAILGROUP;细节设置 PARTIALPASTE_DIALOGLABEL;选择性粘贴配置 PARTIALPASTE_DIRPYRDENOISE;降噪 -PARTIALPASTE_DISTORTION;畸变校正 +PARTIALPASTE_DIRPYREQUALIZER;分频反差调整 +PARTIALPASTE_DISTORTION;畸变矫正 PARTIALPASTE_EPD;色调映射 +PARTIALPASTE_EQUALIZER;小波变换等级 PARTIALPASTE_EVERYTHING;全部 PARTIALPASTE_EXIFCHANGES;对exif所做的修改 PARTIALPASTE_EXPOSURE;曝光 +PARTIALPASTE_FILMSIMULATION;胶片模拟 +PARTIALPASTE_FLATFIELDAUTOSELECT;平场自动选择 +PARTIALPASTE_FLATFIELDBLURRADIUS;平场模糊半径 +PARTIALPASTE_FLATFIELDBLURTYPE;平场模糊类型 +PARTIALPASTE_FLATFIELDCLIPCONTROL;平场剪切控制 +PARTIALPASTE_FLATFIELDFILE;平场文件夹 PARTIALPASTE_GRADIENT;渐变过滤 PARTIALPASTE_HSVEQUALIZER;HSV均衡 PARTIALPASTE_ICMSETTINGS;ICM 设置 +PARTIALPASTE_IMPULSEDENOISE;脉冲噪声降低 PARTIALPASTE_IPTCINFO;IPTC 信息 PARTIALPASTE_LABCURVE;Lab调整 PARTIALPASTE_LENSGROUP;镜头相关设置 @@ -383,91 +462,246 @@ PARTIALPASTE_LENSPROFILE;镜片修正档案 PARTIALPASTE_METAGROUP;元数据 PARTIALPASTE_PCVIGNETTE;暗角滤镜 PARTIALPASTE_PERSPECTIVE;视角 +PARTIALPASTE_PREPROCESS_DEADPIXFILT;坏点过滤器 PARTIALPASTE_PREPROCESS_GREENEQUIL;绿平衡 -PARTIALPASTE_PREPROCESS_LINEDENOISE;线性噪点滤镜 +PARTIALPASTE_PREPROCESS_HOTPIXFILT;热噪过滤器 +PARTIALPASTE_PREPROCESS_LINEDENOISE;线条噪点过滤 +PARTIALPASTE_PRSHARPENING;调整大小后锐化 PARTIALPASTE_RAWCACORR_AUTO;CA自动更正 +PARTIALPASTE_RAWCACORR_CAREDBLUE;红蓝色散 +PARTIALPASTE_RAWEXPOS_BLACK;黑色等级 +PARTIALPASTE_RAWEXPOS_LINEAR;白点纠正 +PARTIALPASTE_RAWEXPOS_PRESER;高光补偿 PARTIALPASTE_RAWGROUP;Raw设置 +PARTIALPASTE_RAW_DCBENHANCE;DCB 增强 +PARTIALPASTE_RAW_DCBITERATIONS;DCB 反复 +PARTIALPASTE_RAW_DMETHOD;解马赛克方法 +PARTIALPASTE_RAW_FALSECOLOR;摩尔纹抑制 +PARTIALPASTE_RAW_IMAGENUM;子图像 +PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE 增强级数 +PARTIALPASTE_RAW_PIXELSHIFT;像素位移 PARTIALPASTE_RESIZE;缩放 +PARTIALPASTE_RETINEX;Retinex增强算法 PARTIALPASTE_RGBCURVES;RGB曲线 PARTIALPASTE_ROTATION;旋转 PARTIALPASTE_SHADOWSHIGHLIGHTS;阴影/高光 PARTIALPASTE_SHARPENEDGE;边缘 PARTIALPASTE_SHARPENING;锐化 PARTIALPASTE_SHARPENMICRO;微处对比 -PARTIALPASTE_VIBRANCE;震动 +PARTIALPASTE_VIBRANCE;鲜艳度 PARTIALPASTE_VIGNETTING;暗角修正 +PARTIALPASTE_WAVELETGROUP;小波变换等级 PARTIALPASTE_WHITEBALANCE;白平衡 PREFERENCES_ADD;添加 PREFERENCES_APPLNEXTSTARTUP;下次启动生效 +PREFERENCES_AUTLISLOW;低 +PREFERENCES_AUTLISMAX;最大 - 所有块平均值 +PREFERENCES_AUTLISSTD;高 +PREFERENCES_AUTLISVLOW;无 +PREFERENCES_AUTLOW;低 PREFERENCES_AUTOMONPROFILE;使用操作系统主显示器的色彩档案 +PREFERENCES_AUTSTD;标准 PREFERENCES_BATCH_PROCESSING;批处理 PREFERENCES_BEHADDALL;全 '添加' PREFERENCES_BEHAVIOR;行为 PREFERENCES_BEHSETALL;全 '设定' +PREFERENCES_BLACKBODY;钨丝灯 PREFERENCES_CACHECLEARALL;全部清除 PREFERENCES_CACHECLEARPROFILES;清除配置 PREFERENCES_CACHECLEARTHUMBS;清除缩略图 PREFERENCES_CACHEMAXENTRIES;最大缓存数量 PREFERENCES_CACHEOPTS;缓存选项 PREFERENCES_CACHETHUMBHEIGHT;最大缩略图高度 +PREFERENCES_CIEART;CIECAM02 优化 +PREFERENCES_CIEART_FRAME;CIECAM02-特定选项 +PREFERENCES_CIEART_LABEL;使用单浮点精度而不是双精度 +PREFERENCES_CIEART_TOOLTIP;如果启用, CIECAM02 将使用单精度浮点计算, 结果是品质轻微下降, 速度则可以提高一些 PREFERENCES_CLIPPINGIND;高光溢出提示 +PREFERENCES_CLUTSCACHE;HaldCLUT 缓存 +PREFERENCES_CLUTSCACHE_LABEL;CLUTs 最大缓存数 +PREFERENCES_CLUTSDIR;HaldCLUT 路径 +PREFERENCES_CMMBPC;黑场补偿 +PREFERENCES_CURVEBBOXPOS;曲线复制/粘贴按钮位置 +PREFERENCES_CURVEBBOXPOS_ABOVE;上 +PREFERENCES_CURVEBBOXPOS_BELOW;下 +PREFERENCES_CURVEBBOXPOS_LEFT;左 +PREFERENCES_CURVEBBOXPOS_RIGHT;右 +PREFERENCES_CUSTPROFBUILD;Custom Processing Profile Builder +PREFERENCES_CUSTPROFBUILDKEYFORMAT;Keys format +PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME;Name +PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;TagID +PREFERENCES_CUSTPROFBUILDPATH;可执行文件路径 +PREFERENCES_CUTOVERLAYBRUSH;裁切遮罩色彩和透明度 PREFERENCES_D50;5000K +PREFERENCES_D50_OLD;5000K PREFERENCES_D55;5500K PREFERENCES_D60;6000K PREFERENCES_D65;6500K +PREFERENCES_DARKFRAMEFOUND;找到 +PREFERENCES_DARKFRAMESHOTS;张 +PREFERENCES_DARKFRAMETEMPLATES;模板 PREFERENCES_DATEFORMAT;日期格式 -PREFERENCES_DATEFORMATHINT;可以使用下列控制符:\n%y : 年\n%m : 月h\n%d : 日\n\n例如,中文日期格式:\n%y/%m/%d +PREFERENCES_DATEFORMATHINT;可以使用下列控制符:\n%y : 年\n%m : 月h\n%d : 日\n\n例如, 中文日期格式:\n%y/%m/%d +PREFERENCES_DAUB_LABEL;使用 Daubechies D6 小波变换而不是 D4 +PREFERENCES_DAUB_TOOLTIP;The Noise Reduction and 小波变换等级 tools use a Debauchies mother wavelet. If you choose D6 instead of D4 you increase the number of orthogonal Daubechies coefficients and probably increase quality of small-scale levels. There is no memory or processing time difference between the two. +PREFERENCES_DIRDARKFRAMES;暗场图像路径 PREFERENCES_DIRHOME;用户文件路径 PREFERENCES_DIRLAST;上次访问路径 PREFERENCES_DIROTHER;其他 PREFERENCES_DIRSELECTDLG;启动时选择图片路径... PREFERENCES_DIRSOFTWARE;软件安装路径 PREFERENCES_EDITORCMDLINE;其他命令行 +PREFERENCES_EDITORLAYOUT;编辑器布局 +PREFERENCES_EXPAUT;进阶 PREFERENCES_EXTERNALEDITOR;外部编辑器 PREFERENCES_FBROWSEROPTS;文件浏览选项 +PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar\n(de-select for low resolution display) PREFERENCES_FILEFORMAT;文件格式 -PREFERENCES_FLATFIELD;平场 PREFERENCES_FLATFIELDFOUND;找到 +PREFERENCES_FLATFIELDSDIR;平场图像路径 +PREFERENCES_FLATFIELDSHOTS;张 +PREFERENCES_FLATFIELDTEMPLATES;模板 +PREFERENCES_FLUOF2;Fluorescent F2 +PREFERENCES_FLUOF7;Fluorescent F7 +PREFERENCES_FLUOF11;Fluorescent F11 PREFERENCES_FORIMAGE;用于图片文件 PREFERENCES_FORRAW;用于Raw文件 +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_GIMPPATH;GIMP安装文件夹 +PREFERENCES_GREY;Output device's Yb luminance (%) +PREFERENCES_GREY05;Yb=05 CIE L#30 +PREFERENCES_GREY10;Yb=10 CIE L#40 +PREFERENCES_GREY15;Yb=15 CIE L#45 +PREFERENCES_GREY18;Settings in main menu +PREFERENCES_GREY18_OLD;Yb=18 CIE L#50 +PREFERENCES_GREY23;Yb=23 CIE L#55 +PREFERENCES_GREY30;Yb=30 CIE L#60 +PREFERENCES_GREY40;Yb=40 CIE L#70 +PREFERENCES_GREYSC;Scene Yb luminance (%) +PREFERENCES_GREYSC18;Yb=18 CIE L#50 +PREFERENCES_GREYSCA;自动 +PREFERENCES_HISTOGRAMPOSITIONLEFT;直方图放置在左面板 +PREFERENCES_HISTOGRAMWORKING;使用工作色彩空间显示直方图和导航器 +PREFERENCES_HISTOGRAM_TOOLTIP;If enabled, the working profile is used for rendering the main histogram and the Navigator panel, otherwise the gamma-corrected output profile is used. PREFERENCES_HLTHRESHOLD;高光溢出阈值 PREFERENCES_ICCDIR;ICC配置路径 -PREFERENCES_IMPROCPARAMS;缺省图片处理参数 -PREFERENCES_INTENT_ABSOLUTE;绝对色彩模式 -PREFERENCES_INTENT_PERCEPTUAL;感知模式 -PREFERENCES_INTENT_RELATIVE;相对色彩模式 +PREFERENCES_IMG_RELOAD_NEEDED;这些改变需要重载图片生效 +PREFERENCES_IMPROCPARAMS;默认图片处理参数 +PREFERENCES_INSPECT_LABEL;检阅 +PREFERENCES_INSPECT_MAXBUFFERS_LABEL;最大缓存图片数 +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_INTENT_ABSOLUTE;绝对比色 +PREFERENCES_INTENT_PERCEPTUAL;可感知 +PREFERENCES_INTENT_RELATIVE;相对比色 PREFERENCES_INTENT_SATURATION;饱和度 +PREFERENCES_INTERNALTHUMBIFUNTOUCHED;如果RAW文件没有修改, 显示内嵌JPEG缩略图 +PREFERENCES_LANG;语言 +PREFERENCES_LANGAUTODETECT;使用系统语言 +PREFERENCES_LEVAUTDN;降噪等级 +PREFERENCES_LEVDN;单元尺寸 +PREFERENCES_LISS;自动多区域平滑 +PREFERENCES_MAX;最大 (Tile) +PREFERENCES_MAXRECENTFOLDERS;最近访问路径历史记录数 +PREFERENCES_MED;中等 (Tile/2) +PREFERENCES_MENUGROUPEXTPROGS;Group "Open with" +PREFERENCES_MENUGROUPFILEOPERATIONS;Group "File operations" +PREFERENCES_MENUGROUPLABEL;Group "Color label" +PREFERENCES_MENUGROUPPROFILEOPERATIONS;Group "Processing profile operations" PREFERENCES_MENUGROUPRANK;组 "评价" +PREFERENCES_MENUOPTIONS;子菜单选项 +PREFERENCES_METADATA;元数据 +PREFERENCES_MIN;Mini (100x115) +PREFERENCES_MONINTENT;默认渲染意图 +PREFERENCES_MONITOR;显示器 +PREFERENCES_MONPROFILE;默认色彩配置文件 +PREFERENCES_MONPROFILE_WARNOSX;受MacOS限制, 仅支持sRGB +PREFERENCES_MULTITAB;多编辑器标签模式 +PREFERENCES_MULTITABDUALMON;多编辑器标签独立模式 +PREFERENCES_NAVGUIDEBRUSH;导航器引导颜色 +PREFERENCES_NAVIGATIONFRAME;导航器 +PREFERENCES_NOISE;降噪 PREFERENCES_OUTDIR;输出路径 PREFERENCES_OUTDIRFOLDER;保存至文件夹 PREFERENCES_OUTDIRFOLDERHINT;将已寸图片放至所选文件夹 PREFERENCES_OUTDIRTEMPLATE;使用模板 -PREFERENCES_OUTDIRTEMPLATEHINT;可以使用下列控制符:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\n这些控制符指向RAW文件所在文件夹及子文件夹。\n\n例如 假如 /home/tom/image/02-09-2006/dsc0012.nef已经打开,控制符的意义如下:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\n如果想将输出文件保存到输入文件所在位置:\n%p1/%f\n\n如果想将输出文件保存至输入文件夹内的'converted'子文件夹:\n%p1/converted/%f\n\n如果想将输出文件保存至 '/home/tom/converted' 并保留按日期所分的子文件夹:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATEHINT;可以使用下列控制符:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\n这些控制符指向RAW文件所在文件夹及子文件夹 \n\n例如 假如 /home/tom/image/02-09-2006/dsc0012.nef已经打开, 控制符的意义如下:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\n如果想将输出文件保存到输入文件所在位置:\n%p1/%f\n\n如果想将输出文件保存至输入文件夹内的'converted'子文件夹:\n%p1/converted/%f\n\n如果想将输出文件保存至 '/home/tom/converted' 并保留按日期所分的子文件夹:\n%p2/converted/%d1/%f +PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails in the file browser +PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Overlay filenames on thumbnails in the editor pannel +PREFERENCES_OVERWRITEOUTPUTFILE;Overwrite existing output files +PREFERENCES_PANFACTORLABEL;Pan rate amplification PREFERENCES_PARSEDEXT;已知扩展名 PREFERENCES_PARSEDEXTADD;添加扩展名 PREFERENCES_PARSEDEXTADDHINT;输入扩展名并按此按钮将其添加至列表 PREFERENCES_PARSEDEXTDELHINT;从列表中删除选中的扩展名 +PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. +PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. +PREFERENCES_PREVDEMO;预览解马赛克方法 +PREFERENCES_PREVDEMO_FAST;快速 +PREFERENCES_PREVDEMO_LABEL;小于100%缩放查看时使用的解马赛克算法: +PREFERENCES_PREVDEMO_SIDECAR;与PP3相同 +PREFERENCES_PRINTER;打印机 (软打样) PREFERENCES_PROFILEHANDLING;图片处理配置管理 PREFERENCES_PROFILELOADPR;配置文件读取优先级 PREFERENCES_PROFILEPRCACHE;缓存中的配置文件 PREFERENCES_PROFILEPRFILE;与图片并列存放的配置文件 +PREFERENCES_PROFILESAVEBOTH;Save processing profile both to the cache and next to the input file PREFERENCES_PROFILESAVECACHE;将配置文件写至缓存 PREFERENCES_PROFILESAVEINPUT;将配置文件与图片并列存放 +PREFERENCES_PROFILESAVELOCATION;处理配置文件存储路径 +PREFERENCES_PROFILE_NONE;无 PREFERENCES_PROPERTY;属性 +PREFERENCES_PRTINTENT;渲染意图 +PREFERENCES_PRTPROFILE;色彩配置文件 PREFERENCES_PSPATH;Adobe Photoshop安装路径 +PREFERENCES_REMEMBERZOOMPAN;记忆缩放和位置 +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_RGBDTL_LABEL;降噪和小波变换等级可用的最大线程数 +PREFERENCES_RGBDTL_TOOLTIP;"0"表示自动选择最大可用线程数 线程越多处理越快, 同时消耗更多内存 +PREFERENCES_SELECTFONT;设置主要字体 +PREFERENCES_SELECTFONT_COLPICKER;设置色彩选择器字体 PREFERENCES_SELECTLANG;选择语言 PREFERENCES_SELECTTHEME;选择主题 +PREFERENCES_SERIALIZE_TIFF_READ;Tiff 读取设定 +PREFERENCES_SERIALIZE_TIFF_READ_LABEL;连续载入tiff文件 +PREFERENCES_SERIALIZE_TIFF_READ_TOOLTIP;开启后可以提高在无压缩tiff图片文件夹中的缩略图生成速度 +PREFERENCES_SET;设置 PREFERENCES_SHOWBASICEXIF;显示基本Exif信息 PREFERENCES_SHOWDATETIME;显示时间日期 +PREFERENCES_SHOWEXPOSURECOMPENSATION;附加曝光补偿 +PREFERENCES_SHOWFILMSTRIPTOOLBAR;显示图像胶片栏 PREFERENCES_SHTHRESHOLD;阴影过暗阈值 +PREFERENCES_SIMPLAUT;工具模式 +PREFERENCES_SINGLETAB;单编辑器栏模式 +PREFERENCES_SINGLETABVERTAB;单编辑器栏模式, 标签栏垂直 +PREFERENCES_SMA;小 (250x287) +PREFERENCES_SND_BATCHQUEUEDONE;队列处理完成 +PREFERENCES_SND_HELP;输入完整路径来指定声音文件, 或者留空表示无声 \nWindows系统声音可以使用 "SystemDefault", "SystemAsterisk" 等 Linux则可以使用 "complete", "window-attention" 等 +PREFERENCES_SND_LNGEDITPROCDONE;编辑器处理完成 +PREFERENCES_SND_TRESHOLDSECS;几秒之后 PREFERENCES_STARTUPIMDIR;启动时路径 +PREFERENCES_STDAUT;标准 PREFERENCES_TAB_BROWSER;文件浏览器 PREFERENCES_TAB_COLORMGR;色彩管理 +PREFERENCES_TAB_DYNAMICPROFILE;动态预设规则 PREFERENCES_TAB_GENERAL;一般 PREFERENCES_TAB_IMPROC;图片处理 +PREFERENCES_TAB_PERFORMANCE;性能和品质 PREFERENCES_TAB_SOUND;音效 +PREFERENCES_THEME;主题 +PREFERENCES_TIMAX;高 +PREFERENCES_TINB;块数量 +PREFERENCES_TISTD;标准 PREFERENCES_TP_LABEL;工具栏 +PREFERENCES_TP_USEICONORTEXT;标签使用图标而不是文本 +PREFERENCES_TP_VSCROLLBAR;隐藏垂直滚动栏 +PREFERENCES_TUNNELMETADATA;无损复制 Exif/IPTC/XMP 到输出文件 +PREFERENCES_USEBUNDLEDPROFILES;启用内置预设 +PREFERENCES_VIEW;输出设备白平衡 (显示器、电视、投影仪等) +PREFERENCES_WAVLEV;在质量为"高"时增加小波变换等级 +PREFERENCES_WLONE;一级 +PREFERENCES_WLTWO;二级 +PREFERENCES_WLZER;无 PREFERENCES_WORKFLOW;排版 PROFILEPANEL_LABEL;处理参数配置 PROFILEPANEL_LOADDLGLABEL;加载处理参数为... @@ -491,7 +725,7 @@ PROGRESSBAR_READY;就绪 PROGRESSBAR_SAVEJPEG;JPEG文件保存中... PROGRESSBAR_SAVEPNG;PNG文件保存中... PROGRESSBAR_SAVETIFF;TIFF文件保存中... -QINFO_ISO;感光度 +QINFO_ISO;ISO QINFO_NOEXIF;Exif数据不可用. SAVEDLG_AUTOSUFFIX;自动加后缀到已经存在的文件 SAVEDLG_FILEFORMAT;文件格式 @@ -570,50 +804,62 @@ TP_COLORAPP_TCMODE_LIGHTNESS;光度 TP_COLORAPP_TCMODE_SATUR;色彩饱和度 TP_CROP_FIXRATIO;比例: TP_CROP_GTDIAGONALS;对角线法则 +TP_CROP_GTEPASSPORT;生物辨识护照 TP_CROP_GTFRAME;框架 TP_CROP_GTGRID;方格 +TP_CROP_GTHARMMEANS;调和平均律 TP_CROP_GTNONE;无 -TP_CROP_GTRULETHIRDS;1/3法则 +TP_CROP_GTRULETHIRDS;三等份法则 +TP_CROP_GTTRIANGLE1;黄金三角 1 +TP_CROP_GTTRIANGLE2;黄金三角 2 TP_CROP_GUIDETYPE;辅助方式: TP_CROP_H;高 TP_CROP_LABEL;剪裁 TP_CROP_PPI;PPI= -TP_CROP_SELECTCROP; 选择预设 +TP_CROP_SELECTCROP;选择预设 TP_CROP_W;宽 TP_CROP_X;x TP_CROP_Y;y TP_DARKFRAME_AUTOSELECT;自动选择 TP_DARKFRAME_LABEL;黑框架 -TP_DEFRINGE_LABEL;边缘优化(除紫边Defringe) +TP_DEFRINGE_LABEL;去色彩边缘(紫边) TP_DEFRINGE_RADIUS;半径 TP_DIRPYRDENOISE_LABEL;降噪 TP_DIRPYRDENOISE_LDETAIL;明亮度细节 TP_DIRPYRDENOISE_LUMA;光亮度/发光度 TP_DIRPYRDENOISE_RGB;RGB -TP_DIRPYREQUALIZER_LUMAFINEST;最佳 +TP_DIRPYREQUALIZER_ALGO;皮肤色彩范围 +TP_DIRPYREQUALIZER_ARTIF;减少杂色 +TP_DIRPYREQUALIZER_HUESKIN;皮肤色相 +TP_DIRPYREQUALIZER_LABEL;分频反差调整 +TP_DIRPYREQUALIZER_LUMACOARSEST;最粗 +TP_DIRPYREQUALIZER_LUMACONTRAST_MINUS;反差 - +TP_DIRPYREQUALIZER_LUMACONTRAST_PLUS;反差 + +TP_DIRPYREQUALIZER_LUMAFINEST;最细 TP_DIRPYREQUALIZER_LUMANEUTRAL;自然 -TP_DIRPYREQUALIZER_THRESHOLD;阀值 -TP_DISTORTION_AMOUNT;程度 +TP_DIRPYREQUALIZER_SKIN;皮肤色彩 针对/保护 +TP_DIRPYREQUALIZER_THRESHOLD;阈值 +TP_DISTORTION_AMOUNT;数量 TP_DISTORTION_LABEL;畸变 -TP_EPD_LABEL;色阶映射 +TP_EPD_LABEL;色调映射 TP_EPD_SCALE;拉伸 TP_EPD_STRENGTH;力度 TP_EXPOSURE_AUTOLEVELS;自动色阶 -TP_EXPOSURE_BLACKLEVEL;黑 +TP_EXPOSURE_BLACKLEVEL;黑点 TP_EXPOSURE_BRIGHTNESS;亮度 TP_EXPOSURE_CLIP;高光溢出 TP_EXPOSURE_COMPRHIGHLIGHTS;高光压缩 -TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;高光压缩阀值 +TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;高光压缩阈值 TP_EXPOSURE_COMPRSHADOWS;阴影压缩 TP_EXPOSURE_CONTRAST;对比度 TP_EXPOSURE_CURVEEDITOR;影调曲线 TP_EXPOSURE_CURVEEDITOR1;色调曲线 1 TP_EXPOSURE_CURVEEDITOR2;色调曲线 2 -TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;请从 “曝光 > 色调曲线” (Exposure > Tone Curve) RawPedia 文章中学到使用2条色调曲线获得好效果 +TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;请从 RawPedia 网站中 Exposure > Tone Curve 文章中了解如何使用双色调曲线 TP_EXPOSURE_EXPCOMP;曝光补偿 TP_EXPOSURE_LABEL;曝光 TP_EXPOSURE_SATURATION;色彩饱和度 -TP_EXPOSURE_TCMODE_FILMLIKE;电影样式 +TP_EXPOSURE_TCMODE_FILMLIKE;仿胶片式 TP_EXPOSURE_TCMODE_LABEL1;曲线模式1 TP_EXPOSURE_TCMODE_LABEL2;曲线模式2 TP_EXPOSURE_TCMODE_SATANDVALBLENDING;饱和度和混合值 @@ -628,7 +874,7 @@ TP_FLATFIELD_BT_VERTHORIZ;垂直 + 水平 TP_FLATFIELD_BT_VERTICAL;垂直 TP_FLATFIELD_LABEL;平场 TP_GAMMA_CURV;伽马 -TP_GAMMA_FREE;自由伽马 +TP_GAMMA_FREE;自定义伽马 TP_GAMMA_OUTPUT;导出伽马 TP_GAMMA_SLOP;斜率 (线性) TP_GRADIENT_CENTER;中心 @@ -645,7 +891,7 @@ TP_HLREC_CIELAB;CIELab模式混合 TP_HLREC_COLOR;色彩延伸 TP_HLREC_LABEL;高光还原 TP_HLREC_LUMINANCE;亮度还原 -TP_HLREC_METHOD;方式: +TP_HLREC_METHOD;方法: TP_HSVEQUALIZER_CHANNEL;频道 TP_HSVEQUALIZER_HUE;H TP_HSVEQUALIZER_LABEL;HSV 平衡 @@ -655,7 +901,7 @@ TP_ICM_INPUTCAMERA;相机缺省 TP_ICM_INPUTCUSTOM;自定义 TP_ICM_INPUTCUSTOM_TOOLTIP;选择你自己的 DCP/ICC 色彩档案 TP_ICM_INPUTDLGLABEL;选择输入ICC配置... -TP_ICM_INPUTEMBEDDED;如可能,使用内置 +TP_ICM_INPUTEMBEDDED;如可能, 使用内置 TP_ICM_INPUTEMBEDDED_TOOLTIP;使用色彩档案嵌入非raw文件 TP_ICM_INPUTNONE;无档案 TP_ICM_INPUTPROFILE;输入配置 @@ -664,10 +910,10 @@ TP_ICM_NOICM;No ICM: sRGB配置 TP_ICM_OUTPUTPROFILE;输出配置 TP_ICM_TONECURVE;使用 DCP 色调曲线 TP_ICM_WORKINGPROFILE;当前配置 -TP_IMPULSEDENOISE_LABEL;降低电磁干扰 +TP_IMPULSEDENOISE_LABEL;降低脉冲噪声 TP_IMPULSEDENOISE_THRESH;阈值 TP_LABCURVE_AVOIDCOLORSHIFT;避免色彩偏移 -TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;使色彩适应当前色彩空间范围,并使用Munsell色矫正。 +TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;使色彩适应当前色彩空间范围, 并使用Munsell色矫正 TP_LABCURVE_BRIGHTNESS;光度 TP_LABCURVE_CHROMATICITY;色度 CIE TP_LABCURVE_CONTRAST;对比度 @@ -677,7 +923,7 @@ TP_LENSGEOM_AUTOCROP;自动剪切 TP_LENSGEOM_FILL;自动填充 TP_LENSGEOM_LABEL;镜头 / 几何 TP_LENSPROFILE_LABEL;镜头矫正档案 -TP_LENSPROFILE_USECA;CA 矫正 +TP_LENSPROFILE_USECA;色散矫正 TP_LENSPROFILE_USEDIST;畸变矫正 TP_LENSPROFILE_USEVIGN;暗角矫正 TP_PCVIGNETTE_FEATHER;羽化 @@ -695,7 +941,7 @@ TP_RAWCACORR_AUTO;自动修正 TP_RAWCACORR_CABLUE;蓝 TP_RAWCACORR_CARED;红 TP_RESIZE_CROPPEDAREA;切出的部分 -TP_RESIZE_FITBOX;Bounding Box 包围盒 +TP_RESIZE_FITBOX;Bounding Box TP_RESIZE_FULLIMAGE;全图 TP_RESIZE_H;高: TP_RESIZE_HEIGHT;高度 @@ -712,7 +958,7 @@ TP_RGBCURVES_CHANNEL;频道 TP_RGBCURVES_GREEN;G TP_RGBCURVES_LABEL;RGB曲线 TP_RGBCURVES_LUMAMODE;光度模式 -TP_RGBCURVES_LUMAMODE_TOOLTIP;光度模式 允许改变R、G、B三种通道光量但不影响色彩。 +TP_RGBCURVES_LUMAMODE_TOOLTIP;光度模式 允许改变R、G、B三种通道光量但不影响色彩 TP_RGBCURVES_RED;R TP_ROTATE_DEGREE;角度 TP_ROTATE_LABEL;旋转 @@ -730,23 +976,23 @@ TP_SHARPENEDGE_AMOUNT;数量 TP_SHARPENEDGE_LABEL;边缘 TP_SHARPENEDGE_PASSES;迭代次数 TP_SHARPENEDGE_THREE;仅光度 -TP_SHARPENING_AMOUNT;程度 +TP_SHARPENING_AMOUNT;数量 TP_SHARPENING_EDRADIUS;半径 TP_SHARPENING_EDTOLERANCE;边缘容差 TP_SHARPENING_HALOCONTROL;光晕控制 -TP_SHARPENING_HCAMOUNT;程度 +TP_SHARPENING_HCAMOUNT;数量 TP_SHARPENING_LABEL;锐化 TP_SHARPENING_METHOD;方式 TP_SHARPENING_ONLYEDGES;仅锐化边缘 TP_SHARPENING_RADIUS;半径 -TP_SHARPENING_RLD;理查森-露西去卷积法 -TP_SHARPENING_RLD_AMOUNT;程度 +TP_SHARPENING_RLD;理查森-露西反卷积法 +TP_SHARPENING_RLD_AMOUNT;数量 TP_SHARPENING_RLD_DAMPING;衰减 TP_SHARPENING_RLD_ITERATIONS;迭代 TP_SHARPENING_THRESHOLD;阈值 -TP_SHARPENING_USM;虚像屏蔽 +TP_SHARPENING_USM;USM锐化 TP_SHARPENMICRO_AMOUNT;数量 -TP_VIGNETTING_AMOUNT;程度 +TP_VIGNETTING_AMOUNT;数量 TP_VIGNETTING_CENTER;中心 TP_VIGNETTING_CENTER_X;中心 X TP_VIGNETTING_CENTER_Y;中心 Y @@ -759,7 +1005,7 @@ TP_WBALANCE_CLOUDY;阴天 TP_WBALANCE_CUSTOM;自定义 TP_WBALANCE_DAYLIGHT;晴天 TP_WBALANCE_EQBLUERED;蓝红平衡 -TP_WBALANCE_FLASH55;莱卡Leica +TP_WBALANCE_FLASH55;徕卡 TP_WBALANCE_FLASH_HEADER;闪光 TP_WBALANCE_GREEN;色度 TP_WBALANCE_LABEL;白平衡 @@ -777,6 +1023,7 @@ TP_WBALANCE_WATER_HEADER;水下 ZOOMPANEL_100;(100%) ZOOMPANEL_NEWCROPWINDOW;开启(新)细节窗口 ZOOMPANEL_ZOOM100;缩放到100%\n快捷键: z +ZOOMPANEL_ZOOMFITCROPSCREEN;适应边缘到屏幕\n快捷键:Alt-f ZOOMPANEL_ZOOMFITSCREEN;适应屏幕\n快捷键: f ZOOMPANEL_ZOOMIN;缩放拉近\n快捷键: + ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - @@ -790,70 +1037,22 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !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. -!CURVEEDITOR_MINMAXCPOINTS;Equalizer -!CURVEEDITOR_NURBS;Control cage -!CURVEEDITOR_PARAMETRIC;Parametric -!CURVEEDITOR_TOOLTIPCOPY;Copy current curve to clipboard. -!CURVEEDITOR_TOOLTIPPASTE;Paste curve from clipboard. -!DONT_SHOW_AGAIN;Don't show this message again. -!DYNPROFILEEDITOR_DELETE;Delete -!DYNPROFILEEDITOR_EDIT;Edit -!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_MOVE_DOWN;Move Down -!DYNPROFILEEDITOR_MOVE_UP;Move Up -!DYNPROFILEEDITOR_NEW;New -!DYNPROFILEEDITOR_NEW_RULE;New Dynamic Profile Rule -!DYNPROFILEEDITOR_PROFILE;Processing Profile !EDIT_OBJECT_TOOLTIP;Displays a widget on the preview window which lets you adjust this tool. !EDIT_PIPETTE_TOOLTIP;To add an adjustment point to the curve, hold the Ctrl key while left-clicking the desired spot in the image preview.\nTo adjust the point, hold the Ctrl key while left-clicking the corresponding area in the preview, then let go of Ctrl (unless you desire fine control) and while still holding the left mouse button move the mouse up or down to move that point up or down in the curve. -!EXIFFILTER_EXPOSURECOMPENSATION;Exposure compensation (EV) -!EXIFFILTER_METADATAFILTER;Enable metadata filters +!EXIFPANEL_SHOWALL;Show all !EXPORT_BYPASS;Processing steps to bypass -!EXPORT_BYPASS_DEFRINGE;Bypass Defringe -!EXPORT_BYPASS_DIRPYRDENOISE;Bypass Noise Reduction -!EXPORT_BYPASS_DIRPYREQUALIZER;Bypass Contrast by Detail Levels -!EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels -!EXPORT_BYPASS_RAW_CA;Bypass [raw] Chromatic Aberration Correction -!EXPORT_BYPASS_RAW_CCSTEPS;Bypass [raw] False Color Suppression !EXPORT_BYPASS_RAW_DCB_ENHANCE;Bypass [raw] DCB Enhancement Steps !EXPORT_BYPASS_RAW_DCB_ITERATIONS;Bypass [raw] DCB Iterations -!EXPORT_BYPASS_RAW_DF;Bypass [raw] Dark-Frame -!EXPORT_BYPASS_RAW_GREENTHRESH;Bypass [raw] Green Equilibration !EXPORT_BYPASS_RAW_LMMSE_ITERATIONS;Bypass [raw] LMMSE Enhancement Steps -!EXPORT_BYPASS_SHARPENEDGE;Bypass Edge Sharpening -!EXPORT_BYPASS_SHARPENING;Bypass Sharpening -!EXPORT_BYPASS_SHARPENMICRO;Bypass Microcontrast !EXPORT_BYPASS_SH_HQ;Bypass Sharp Mask Shadows/Highlights !EXPORT_INSTRUCTIONS;Fast Export options provide overrides to bypass time and resource consuming development settings and to run queue processing using the fast export settings instead. This method is recommended for quicker generation of lower resolution images when speed is a priority or when resized output is desired for one or many images without making modifications to their saved development parameters. !EXPORT_PIPELINE;Processing pipeline -!EXPORT_RAW_DMETHOD;Demosaic method !EXPORT_USE_FAST_PIPELINE;Dedicated (full processing on resized image) !EXPORT_USE_FAST_PIPELINE_TIP;Use a dedicated processing pipeline for images in Fast Export mode, that trades speed for quality. Resizing of the image is done as early as possible, instead of doing it at the end like in the normal pipeline. The speedup can be significant, but be prepared to see artifacts and a general degradation of output quality. !EXPORT_USE_NORMAL_PIPELINE;Standard (bypass some steps, resize at the end) -!EXTPROGTARGET_2;queue-processed -!FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... -!FILEBROWSER_APPLYPROFILE_PARTIAL;Apply - partial -!FILEBROWSER_AUTODARKFRAME;Auto dark-frame -!FILEBROWSER_AUTOFLATFIELD;Auto flat-field -!FILEBROWSER_BROWSEPATHBUTTONHINT;Click to browse to the chosen path. !FILEBROWSER_BROWSEPATHHINT;Type a path to navigate to.\n\nKeyboard shortcuts:\nCtrl-o to focus to the path text box.\nEnter / Ctrl-Enter to browse there;\nEsc to clear changes.\nShift-Esc to remove focus.\n\nPath shortcuts:\n~ - user's home directory.\n! - user's pictures directory !FILEBROWSER_COLORLABEL_TOOLTIP;Color label.\n\nUse dropdown menu or shortcuts:\nShift-Ctrl-0 No Color\nShift-Ctrl-1 Red\nShift-Ctrl-2 Yellow\nShift-Ctrl-3 Green\nShift-Ctrl-4 Blue\nShift-Ctrl-5 Purple -!FILEBROWSER_DARKFRAME;Dark-frame -!FILEBROWSER_DELETEDLGMSGINCLPROC;Are you sure you want to delete the selected %1 files including a queue-processed version? -!FILEBROWSER_FLATFIELD;Flat-Field -!FILEBROWSER_MOVETODARKFDIR;Move to dark-frames directory -!FILEBROWSER_MOVETOFLATFIELDDIR;Move to flat-fields directory -!FILEBROWSER_POPUPCOLORLABEL0;Label: None -!FILEBROWSER_POPUPCOLORLABEL1;Label: Red -!FILEBROWSER_POPUPCOLORLABEL2;Label: Yellow -!FILEBROWSER_POPUPCOLORLABEL3;Label: Green -!FILEBROWSER_POPUPCOLORLABEL4;Label: Blue -!FILEBROWSER_POPUPCOLORLABEL5;Label: Purple -!FILEBROWSER_POPUPRANK;Rank -!FILEBROWSER_POPUPRANK0;Unrank !FILEBROWSER_QUERYHINT;Type filenames to search for. Supports partial filenames. Separate the search terms using commas, e.g.\n1001,1004,1199\n\nExclude search terms by prefixing them with !=\ne.g.\n!=1001,1004,1199\n\nShortcuts:\nCtrl-f - focus the Find box,\nEnter - search,\nEsc - clear the Find box,\nShift-Esc - defocus the Find box. -!FILEBROWSER_RESETDEFAULTPROFILE;Reset to default !FILEBROWSER_SHOWCOLORLABEL1HINT;Show images labeled Red.\nShortcut: Alt-1 !FILEBROWSER_SHOWCOLORLABEL2HINT;Show images labeled Yellow.\nShortcut: Alt-2 !FILEBROWSER_SHOWCOLORLABEL3HINT;Show images labeled Green.\nShortcut: Alt-3 @@ -867,16 +1066,6 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !FILEBROWSER_SHOWUNCOLORHINT;Show images without a color label.\nShortcut: Alt-0 !FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives. !FILEBROWSER_UNRANK_TOOLTIP;Unrank.\nShortcut: Shift-0 -!FILECHOOSER_FILTER_ANY;All files -!FILECHOOSER_FILTER_COLPROF;Color profiles -!FILECHOOSER_FILTER_CURVE;Curve files -!FILECHOOSER_FILTER_LCP;Lens correction profiles -!FILECHOOSER_FILTER_PP;Processing profiles -!FILECHOOSER_FILTER_SAME;Same format as current photo -!FILECHOOSER_FILTER_TIFF;TIFF files -!GENERAL_APPLY;Apply -!GENERAL_ASIMAGE;As Image -!GENERAL_OPEN;Open !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_BAR;Show/Hide RGB indicator bar.\nRight-click on image preview to freeze/unfreeze. !HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram. @@ -1232,6 +1421,12 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !HISTORY_MSG_482;CAM02 - Green scene !HISTORY_MSG_483;CAM02 - Yb scene !HISTORY_MSG_484;CAM02 - Auto Yb scene +!HISTORY_MSG_485;Lens Correction +!HISTORY_MSG_486;Lens Correction - Camera +!HISTORY_MSG_487;Lens Correction - Lens +!HISTORY_MSG_488;HDR Tone Mapping +!HISTORY_MSG_489;HDR TM - Threshold +!HISTORY_MSG_490;HDR TM - Amount !IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider. !IPTCPANEL_CITYHINT;Enter the name of the city pictured in this image. !IPTCPANEL_COPYRIGHT;Copyright notice @@ -1257,6 +1452,10 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !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. +!LENSPROFILE_CORRECTION_AUTOMATCH;Auto-matched correction parameters +!LENSPROFILE_CORRECTION_LCPFILE;LCP File +!LENSPROFILE_CORRECTION_MANUAL;Manual correction parameters +!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. !MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the next image relative to image opened in the Editor.\nShortcut: Shift-F4\n\nTo navigate to the next image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F4 !MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the previous image relative to image opened in the Editor.\nShortcut: Shift-F3\n\nTo navigate to the previous image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F3 !MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchronize the File Browser or Filmstrip with the Editor to reveal the thumbnail of the currently opened image, and clear any active filters.\nShortcut: x\n\nAs above, but without clearing active filters:\nShortcut: y\n(Note that the thumbnail of the opened image will not be shown if filtered out). @@ -1265,17 +1464,10 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !MAIN_MSG_SETPATHFIRST;You first have to set a target path in Preferences in order to use this function! !MAIN_MSG_TOOMANYOPENEDITORS;Too many open editors.\nPlease close an editor to continue. !MAIN_MSG_WRITEFAILED;Failed to write\n"%1"\n\nMake sure that the folder exists and that you have write permission to it. -!MAIN_TAB_COLOR_TOOLTIP;Shortcut: Alt-c -!MAIN_TAB_DETAIL_TOOLTIP;Shortcut: Alt-d -!MAIN_TAB_EXPOSURE_TOOLTIP;Shortcut: Alt-e -!MAIN_TAB_INSPECT; Inspect -!MAIN_TAB_METADATA_TOOLTIP;Shortcut: Alt-m -!MAIN_TAB_TRANSFORM_TOOLTIP;Shortcut: Alt-t -!MAIN_TAB_WAVELET;Wavelet -!MAIN_TAB_WAVELET_TOOLTIP;Shortcut: Alt-w !MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 9 !MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 !MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 9 +!MAIN_TOOLTIP_BACKCOLOR3;Background color of the preview: Middle grey\nShortcut: 9 !MAIN_TOOLTIP_BEFOREAFTERLOCK;Lock / Unlock the Before view\n\nLock: keep the Before view unchanged.\nUseful to evaluate the cumulative effect of multiple tools.\nAdditionally, comparisons can be made to any state in the History.\n\nUnlock: the Before view will follow the After view one step behind, showing the image before the effect of the currently used tool. !MAIN_TOOLTIP_PREVIEWB;Preview the Blue channel.\nShortcut: b !MAIN_TOOLTIP_PREVIEWFOCUSMASK;Preview the Focus Mask.\nShortcut: Shift-f\n\nMore accurate on images with shallow depth of field, low noise and at higher zoom levels.\n\nTo improve detection accuracy for noisy images evaluate at smaller zoom, about 10-30%. @@ -1284,178 +1476,13 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !MONITOR_PROFILE_SYSTEM;System default !OPTIONS_DEFIMG_MISSING;The default profile for non-raw photos could not be found or is not set.\n\nPlease check your profiles' directory, it may be missing or damaged.\n\nDefault internal values will be used. !OPTIONS_DEFRAW_MISSING;The default profile for raw photos could not be found or is not set.\n\nPlease check your profiles' directory, it may be missing or damaged.\n\nDefault internal values will be used. -!PARTIALPASTE_COLORTONING;Color toning -!PARTIALPASTE_DEFRINGE;Defringe -!PARTIALPASTE_DIRPYREQUALIZER;Contrast by detail levels -!PARTIALPASTE_EQUALIZER;Wavelet levels -!PARTIALPASTE_FILMSIMULATION;Film simulation -!PARTIALPASTE_FLATFIELDAUTOSELECT;Flat-field auto-selection -!PARTIALPASTE_FLATFIELDBLURRADIUS;Flat-field blur radius -!PARTIALPASTE_FLATFIELDBLURTYPE;Flat-field blur type -!PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field clip control -!PARTIALPASTE_FLATFIELDFILE;Flat-field file -!PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction -!PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter -!PARTIALPASTE_PREPROCESS_HOTPIXFILT;Hot pixel filter -!PARTIALPASTE_PRSHARPENING;Post-resize sharpening -!PARTIALPASTE_RAWCACORR_CAREDBLUE;CA red & blue -!PARTIALPASTE_RAWEXPOS_BLACK;Black levels -!PARTIALPASTE_RAWEXPOS_LINEAR;White point correction -!PARTIALPASTE_RAWEXPOS_PRESER;Highlight preservation -!PARTIALPASTE_RAW_DCBENHANCE;DCB enhancement -!PARTIALPASTE_RAW_DCBITERATIONS;DCB iterations -!PARTIALPASTE_RAW_DMETHOD;Demosaic method -!PARTIALPASTE_RAW_FALSECOLOR;False color suppression -!PARTIALPASTE_RAW_IMAGENUM;Sub-image -!PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps -!PARTIALPASTE_RAW_PIXELSHIFT;PixelShift -!PARTIALPASTE_RETINEX;Retinex -!PARTIALPASTE_WAVELETGROUP;Wavelet Levels -!PREFERENCES_AUTLISLOW;Low -!PREFERENCES_AUTLISMAX;Max - Average of all tiles -!PREFERENCES_AUTLISSTD;High -!PREFERENCES_AUTLISVLOW;None -!PREFERENCES_AUTLOW;Low -!PREFERENCES_AUTSTD;Standard +!PARTIALPASTE_TM_FATTAL;HDR Tone mapping +!PREFERENCES_AUTOSAVE_TP_OPEN;Automatically save tools collapsed/expanded\nstate before exiting !PREFERENCES_BEHADDALLHINT;Set all parameters to the Add mode.\nAdjustments of parameters in the batch tool panel will be deltas to the stored values. !PREFERENCES_BEHSETALLHINT;Set all parameters to the Set mode.\nAdjustments of parameters in the batch tool panel will be absolute, the actual values will be displayed. -!PREFERENCES_BLACKBODY;Tungsten -!PREFERENCES_CIEART;CIECAM02 optimization -!PREFERENCES_CIEART_FRAME;CIECAM02-Specific Settings -!PREFERENCES_CIEART_LABEL;Use float precision instead of double -!PREFERENCES_CIEART_TOOLTIP;If enabled, CIECAM02 calculations are performed in the single-precision floating-point format instead of the double-precision one. This provides a small increase in speed at the expense of a negligible loss of quality. -!PREFERENCES_CLUTSCACHE;HaldCLUT Cache -!PREFERENCES_CLUTSCACHE_LABEL;Maximum number of cached CLUTs -!PREFERENCES_CLUTSDIR;HaldCLUT directory -!PREFERENCES_CMMBPC;Black point compensation -!PREFERENCES_CURVEBBOXPOS;Position of curve copy & paste buttons -!PREFERENCES_CURVEBBOXPOS_ABOVE;Above -!PREFERENCES_CURVEBBOXPOS_BELOW;Below -!PREFERENCES_CURVEBBOXPOS_LEFT;Left -!PREFERENCES_CURVEBBOXPOS_RIGHT;Right -!PREFERENCES_CUSTPROFBUILD;Custom Processing Profile Builder !PREFERENCES_CUSTPROFBUILDHINT;Executable (or script) file called when a new initial processing profile should be generated for an image.\n\nThe path of the communication file (*.ini style, a.k.a. "Keyfile") is added as a command line parameter. It contains various parameters required for the scripts and image Exif to allow a rules-based processing profile generation.\n\nWARNING: You are responsible for using double quotes where necessary if you're using paths containing spaces. -!PREFERENCES_CUSTPROFBUILDKEYFORMAT;Keys format -!PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME;Name -!PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;TagID -!PREFERENCES_CUSTPROFBUILDPATH;Executable path -!PREFERENCES_CUTOVERLAYBRUSH;Crop mask color/transparency -!PREFERENCES_D50_OLD;5000K -!PREFERENCES_DARKFRAME;Dark-Frame -!PREFERENCES_DARKFRAMEFOUND;Found -!PREFERENCES_DARKFRAMESHOTS;shots -!PREFERENCES_DARKFRAMETEMPLATES;templates -!PREFERENCES_DAUB_LABEL;Use Daubechies D6 wavelets instead of D4 -!PREFERENCES_DAUB_TOOLTIP;The Noise Reduction and Wavelet Levels tools use a Debauchies mother wavelet. If you choose D6 instead of D4 you increase the number of orthogonal Daubechies coefficients and probably increase quality of small-scale levels. There is no memory or processing time difference between the two. -!PREFERENCES_DIRDARKFRAMES;Dark-frames directory -!PREFERENCES_EDITORLAYOUT;Editor Layout -!PREFERENCES_EXPAUT;Expert -!PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar\n(de-select for low resolution display) -!PREFERENCES_FILMSIMULATION;Film Simulation -!PREFERENCES_FLATFIELDSDIR;Flat-fields directory -!PREFERENCES_FLATFIELDSHOTS;shots -!PREFERENCES_FLATFIELDTEMPLATES;templates -!PREFERENCES_FLUOF2;Fluorescent F2 -!PREFERENCES_FLUOF7;Fluorescent F7 -!PREFERENCES_FLUOF11;Fluorescent F11 -!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_GREY;Output device's Yb luminance (%) -!PREFERENCES_GREY05;Yb=05 CIE L#30 -!PREFERENCES_GREY10;Yb=10 CIE L#40 -!PREFERENCES_GREY15;Yb=15 CIE L#45 -!PREFERENCES_GREY18;Settings in main menu -!PREFERENCES_GREY18_OLD;Yb=18 CIE L#50 -!PREFERENCES_GREY23;Yb=23 CIE L#55 -!PREFERENCES_GREY30;Yb=30 CIE L#60 -!PREFERENCES_GREY40;Yb=40 CIE L#70 -!PREFERENCES_GREYSC;Scene Yb luminance (%) -!PREFERENCES_GREYSC18;Yb=18 CIE L#50 -!PREFERENCES_GREYSCA;Automatic -!PREFERENCES_HISTOGRAMPOSITIONLEFT;Histogram in left panel -!PREFERENCES_HISTOGRAMWORKING;Use working profile for main histogram and Navigator -!PREFERENCES_HISTOGRAM_TOOLTIP;If enabled, the working profile is used for rendering the main histogram and the Navigator panel, otherwise the gamma-corrected output profile is used. -!PREFERENCES_IMG_RELOAD_NEEDED;These changes require the image to be reloaded (or a new image to be opened) to take effect. -!PREFERENCES_INSPECT_LABEL;Inspect -!PREFERENCES_INSPECT_MAXBUFFERS_LABEL;Maximum number of cached images -!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_INTERNALTHUMBIFUNTOUCHED;Show embedded JPEG thumbnail if raw is unedited -!PREFERENCES_LANG;Language -!PREFERENCES_LANGAUTODETECT;Use system language -!PREFERENCES_LEVAUTDN;Denoising level -!PREFERENCES_LEVDN;Cell size -!PREFERENCES_LISS;Auto multi-zone smoothing -!PREFERENCES_MAX;Maxi (Tile) -!PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders -!PREFERENCES_MED;Medium (Tile/2) -!PREFERENCES_MENUGROUPEXTPROGS;Group "Open with" -!PREFERENCES_MENUGROUPFILEOPERATIONS;Group "File operations" -!PREFERENCES_MENUGROUPLABEL;Group "Color label" -!PREFERENCES_MENUGROUPPROFILEOPERATIONS;Group "Processing profile operations" -!PREFERENCES_MENUOPTIONS;Context Menu Options -!PREFERENCES_METADATA;Metadata -!PREFERENCES_MIN;Mini (100x115) -!PREFERENCES_MONINTENT;Default rendering intent -!PREFERENCES_MONITOR;Monitor -!PREFERENCES_MONPROFILE;Default color profile -!PREFERENCES_MONPROFILE_WARNOSX;Due to MacOS limitations, only sRGB is supported. -!PREFERENCES_MULTITAB;Multiple Editor Tabs Mode -!PREFERENCES_MULTITABDUALMON;Multiple Editor Tabs In Own Window Mode -!PREFERENCES_NAVGUIDEBRUSH;Navigator guide color -!PREFERENCES_NAVIGATIONFRAME;Navigation -!PREFERENCES_NOISE;Noise Reduction -!PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails in the file browser -!PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Overlay filenames on thumbnails in the editor pannel -!PREFERENCES_OVERWRITEOUTPUTFILE;Overwrite existing output files -!PREFERENCES_PANFACTORLABEL;Pan rate amplification -!PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. -!PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. -!PREFERENCES_PREVDEMO;Preview Demosaic Method -!PREFERENCES_PREVDEMO_FAST;Fast -!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_PROFILE_NONE;None -!PREFERENCES_PRTINTENT;Rendering intent -!PREFERENCES_PRTPROFILE;Color profile -!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_RGBDTL_LABEL;Max number of threads for Noise Reduction and Wavelet Levels -!PREFERENCES_RGBDTL_TOOLTIP;Leave the setting at "0" to automatically use as many threads as possible. The more threads run in parallel, the faster the computation. Refer to RawPedia for memory requirements. -!PREFERENCES_SELECTFONT;Select main font -!PREFERENCES_SELECTFONT_COLPICKER;Select Color Picker's font -!PREFERENCES_SERIALIZE_TIFF_READ;Tiff Read Settings -!PREFERENCES_SERIALIZE_TIFF_READ_LABEL;Serialize read of tiff files -!PREFERENCES_SERIALIZE_TIFF_READ_TOOLTIP;When working with folders full of uncompressed tiff files enabling this option can increase performance of thumb generation. -!PREFERENCES_SET;Set -!PREFERENCES_SHOWEXPOSURECOMPENSATION;Append exposure compensation -!PREFERENCES_SHOWFILMSTRIPTOOLBAR;Show filmstrip toolbar -!PREFERENCES_SIMPLAUT;Tool mode -!PREFERENCES_SINGLETAB;Single Editor Tab Mode -!PREFERENCES_SINGLETABVERTAB;Single Editor Tab Mode, Vertical Tabs -!PREFERENCES_SMA;Small (250x287) -!PREFERENCES_SND_BATCHQUEUEDONE;Queue processing done -!PREFERENCES_SND_HELP;Enter a full file path to set a sound, or leave blank for no sound.\nFor system sounds on Windows use "SystemDefault", "SystemAsterisk" etc., and on Linux use "complete", "window-attention" etc. -!PREFERENCES_SND_LNGEDITPROCDONE;Editor processing done -!PREFERENCES_SND_TRESHOLDSECS;After seconds -!PREFERENCES_STDAUT;Standard -!PREFERENCES_TAB_DYNAMICPROFILE;Dynamic Profile Rules -!PREFERENCES_TAB_PERFORMANCE;Performance & Quality -!PREFERENCES_THEME;Theme -!PREFERENCES_TIMAX;High -!PREFERENCES_TINB;Number of tiles -!PREFERENCES_TISTD;Standard -!PREFERENCES_TP_USEICONORTEXT;Use tab icons instead of text -!PREFERENCES_TP_VSCROLLBAR;Hide vertical scrollbar -!PREFERENCES_TUNNELMETADATA;Copy Exif/IPTC/XMP unchanged to output file -!PREFERENCES_USEBUNDLEDPROFILES;Use bundled profiles -!PREFERENCES_VIEW;Output device's white balance (monitor, TV, projector, viewing, etc.) -!PREFERENCES_WAVLEV;Increase wavelet level in quality 'high' -!PREFERENCES_WLONE;One level -!PREFERENCES_WLTWO;Two levels -!PREFERENCES_WLZER;No +!PREFERENCES_DIRECTORIES;Directories +!PREFERENCES_SAVE_TP_OPEN_NOW;Save tools collapsed/expanded state now !PROFILEPANEL_COPYPPASTE;Parameters to copy !PROFILEPANEL_GLOBALPROFILES;Bundled profiles !PROFILEPANEL_LOADPPASTE;Parameters to load @@ -1467,10 +1494,19 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !PROGRESSBAR_PROCESSING_PROFILESAVED;Processing profile saved !PROGRESSBAR_SNAPSHOT_ADDED;Snapshot added !PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!QINFO_FRAMECOUNT;%2 frames +!QINFO_HDR;HDR / %2 frame(s) +!QINFO_PIXELSHIFT;Pixel Shift / %2 frame(s) +!SAMPLEFORMAT_0;Unknown data format +!SAMPLEFORMAT_1;Unsigned 8 bits +!SAMPLEFORMAT_2;Unsigned 16 bits +!SAMPLEFORMAT_4;LogLuv 24 bits +!SAMPLEFORMAT_8;LogLuv 32 bits +!SAMPLEFORMAT_16;32 bits 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. !SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. -!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the output profile. -!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate de rendering generated by the output profile of the ICM tool. Most useful for simulating printing outputs. +!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the Printer profile. +!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate the printer's output by using the Printer profile set in Preferences > Color Management. !THRESHOLDSELECTOR_B;Bottom !THRESHOLDSELECTOR_BL;Bottom-left !THRESHOLDSELECTOR_BR;Bottom-right @@ -1571,7 +1607,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !TP_COLORAPP_TCMODE_LABEL1;Curve mode 1 !TP_COLORAPP_TCMODE_LABEL2;Curve mode 2 !TP_COLORAPP_TCMODE_LABEL3;Curve chroma mode -!TP_COLORAPP_TEMP_TOOLTIP;To select an illuminant always Tint=1.\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\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504 !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_WBCAM;WB [RT+CAT02] + [output] @@ -1615,10 +1651,6 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !TP_COLORTONING_TWOBY;Special a* and b* !TP_COLORTONING_TWOCOLOR_TOOLTIP;Standard chroma:\nLinear response, a* = b*.\n\nSpecial chroma:\nLinear response, a* = b*, but unbound - try under the diagonal.\n\nSpecial a* and b*:\nLinear response unbound with separate curves for a* and b*. Intended for special effects.\n\nSpecial chroma 2 colors:\nMore predictable. !TP_COLORTONING_TWOSTD;Standard chroma -!TP_CROP_GTEPASSPORT;Biometric Passport -!TP_CROP_GTHARMMEANS;Harmonic Means -!TP_CROP_GTTRIANGLE1;Golden Triangles 1 -!TP_CROP_GTTRIANGLE2;Golden Triangles 2 !TP_DEFRINGE_THRESHOLD;Threshold !TP_DIRPYRDENOISE_3X3;3×3 !TP_DIRPYRDENOISE_3X3_SOFT;3×3 soft @@ -1678,16 +1710,8 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !TP_DIRPYRDENOISE_SHALBI;High !TP_DIRPYRDENOISE_SLI;Slider !TP_DIRPYRDENOISE_TILELABEL;Tile size=%1, Center: Tx=%2 Ty=%3 -!TP_DIRPYREQUALIZER_ALGO;Skin Color Range !TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fine: closer to the colors of the skin, minimizing the action on other colors\nLarge: avoid more artifacts. -!TP_DIRPYREQUALIZER_ARTIF;Reduce artifacts -!TP_DIRPYREQUALIZER_HUESKIN;Skin hue !TP_DIRPYREQUALIZER_HUESKIN_TOOLTIP;This pyramid is for the upper part, so far as the algorithm at its maximum efficiency.\nTo the lower part, the transition zones.\nIf you need to move the area significantly to the left or right - or if there are artifacts: the white balance is incorrect\nYou can slightly reduce the zone to prevent the rest of the image is affected. -!TP_DIRPYREQUALIZER_LABEL;Contrast by Detail Levels -!TP_DIRPYREQUALIZER_LUMACOARSEST;Coarsest -!TP_DIRPYREQUALIZER_LUMACONTRAST_MINUS;Contrast - -!TP_DIRPYREQUALIZER_LUMACONTRAST_PLUS;Contrast + -!TP_DIRPYREQUALIZER_SKIN;Skin targetting/protection !TP_DIRPYREQUALIZER_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_DIRPYREQUALIZER_TOOLTIP;Attempts to reduce artifacts in the transitions between skin colors (hue, chroma, luma) and the rest of the image. !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. @@ -1950,6 +1974,9 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !TP_SHARPENMICRO_LABEL;Microcontrast !TP_SHARPENMICRO_MATRIX;3×3 matrix instead of 5×5 !TP_SHARPENMICRO_UNIFORMITY;Uniformity +!TP_TM_FATTAL_AMOUNT;Amount +!TP_TM_FATTAL_LABEL;HDR Tone Mapping +!TP_TM_FATTAL_THRESHOLD;Threshold !TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift !TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH !TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones @@ -2157,4 +2184,3 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !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_TUNGSTEN;Tungsten -!ZOOMPANEL_ZOOMFITCROPSCREEN;Fit crop to screen\nShortcut: Alt-f diff --git a/rtdata/languages/Chinese (Traditional) b/rtdata/languages/Chinese (Traditional) index 61a805d6c..2476aeb41 100644 --- a/rtdata/languages/Chinese (Traditional) +++ b/rtdata/languages/Chinese (Traditional) @@ -471,6 +471,7 @@ TP_WBALANCE_TEMPERATURE;色溫 !EXIFFILTER_EXPOSURECOMPENSATION;Exposure compensation (EV) !EXIFFILTER_FILETYPE;File type !EXIFFILTER_METADATAFILTER;Enable metadata filters +!EXIFPANEL_SHOWALL;Show all !EXPORT_BYPASS;Processing steps to bypass !EXPORT_BYPASS_ALL;Select / Unselect All !EXPORT_BYPASS_DEFRINGE;Bypass Defringe @@ -589,7 +590,7 @@ TP_WBALANCE_TEMPERATURE;色溫 !HISTORY_MSG_82;Profile changed !HISTORY_MSG_83;S/H - Sharp mask !HISTORY_MSG_84;Perspective correction -!HISTORY_MSG_85;LCP +!HISTORY_MSG_85;Lens Correction - LCP file !HISTORY_MSG_86;RGB Curves - Luminosity mode !HISTORY_MSG_87;Impulse Noise Reduction !HISTORY_MSG_88;Impulse NR threshold @@ -972,6 +973,12 @@ TP_WBALANCE_TEMPERATURE;色溫 !HISTORY_MSG_482;CAM02 - Green scene !HISTORY_MSG_483;CAM02 - Yb scene !HISTORY_MSG_484;CAM02 - Auto Yb scene +!HISTORY_MSG_485;Lens Correction +!HISTORY_MSG_486;Lens Correction - Camera +!HISTORY_MSG_487;Lens Correction - Lens +!HISTORY_MSG_488;HDR Tone Mapping +!HISTORY_MSG_489;HDR TM - Threshold +!HISTORY_MSG_490;HDR TM - Amount !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider. !IPTCPANEL_CITYHINT;Enter the name of the city pictured in this image. @@ -998,6 +1005,10 @@ TP_WBALANCE_TEMPERATURE;色溫 !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. +!LENSPROFILE_CORRECTION_AUTOMATCH;Auto-matched correction parameters +!LENSPROFILE_CORRECTION_LCPFILE;LCP File +!LENSPROFILE_CORRECTION_MANUAL;Manual correction parameters +!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. !MAIN_BUTTON_FULLSCREEN;Fullscreen !MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the next image relative to image opened in the Editor.\nShortcut: Shift-F4\n\nTo navigate to the next image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F4 !MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the previous image relative to image opened in the Editor.\nShortcut: Shift-F3\n\nTo navigate to the previous image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F3 @@ -1032,6 +1043,7 @@ TP_WBALANCE_TEMPERATURE;色溫 !MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 9 !MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 !MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 9 +!MAIN_TOOLTIP_BACKCOLOR3;Background color of the preview: Middle grey\nShortcut: 9 !MAIN_TOOLTIP_BEFOREAFTERLOCK;Lock / Unlock the Before view\n\nLock: keep the Before view unchanged.\nUseful to evaluate the cumulative effect of multiple tools.\nAdditionally, comparisons can be made to any state in the History.\n\nUnlock: the Before view will follow the After view one step behind, showing the image before the effect of the currently used tool. !MAIN_TOOLTIP_PREVIEWB;Preview the Blue channel.\nShortcut: b !MAIN_TOOLTIP_PREVIEWFOCUSMASK;Preview the Focus Mask.\nShortcut: Shift-f\n\nMore accurate on images with shallow depth of field, low noise and at higher zoom levels.\n\nTo improve detection accuracy for noisy images evaluate at smaller zoom, about 10-30%. @@ -1081,7 +1093,7 @@ TP_WBALANCE_TEMPERATURE;色溫 !PARTIALPASTE_HSVEQUALIZER;HSV equalizer !PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction !PARTIALPASTE_LABCURVE;L*a*b* adjustments -!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_LENSPROFILE;Profiled lens correction !PARTIALPASTE_PCVIGNETTE;Vignette filter !PARTIALPASTE_PERSPECTIVE;Perspective !PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter @@ -1101,11 +1113,12 @@ TP_WBALANCE_TEMPERATURE;色溫 !PARTIALPASTE_RAW_FALSECOLOR;False color suppression !PARTIALPASTE_RAW_IMAGENUM;Sub-image !PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps -!PARTIALPASTE_RAW_PIXELSHIFT;PixelShift +!PARTIALPASTE_RAW_PIXELSHIFT;Pixel Shift !PARTIALPASTE_RETINEX;Retinex !PARTIALPASTE_RGBCURVES;RGB curves !PARTIALPASTE_SHARPENEDGE;Edges !PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_TM_FATTAL;HDR Tone mapping !PARTIALPASTE_VIBRANCE;Vibrance !PARTIALPASTE_WAVELETGROUP;Wavelet Levels !PREFERENCES_ADD;Add @@ -1115,6 +1128,7 @@ TP_WBALANCE_TEMPERATURE;色溫 !PREFERENCES_AUTLISVLOW;None !PREFERENCES_AUTLOW;Low !PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +!PREFERENCES_AUTOSAVE_TP_OPEN;Automatically save tools collapsed/expanded\nstate before exiting !PREFERENCES_AUTSTD;Standard !PREFERENCES_BATCH_PROCESSING;Batch Processing !PREFERENCES_BEHADDALL;All to 'Add' @@ -1148,18 +1162,16 @@ TP_WBALANCE_TEMPERATURE;色溫 !PREFERENCES_D55;5500K !PREFERENCES_D60;6000K !PREFERENCES_D65;6500K -!PREFERENCES_DARKFRAME;Dark-Frame !PREFERENCES_DARKFRAMEFOUND;Found !PREFERENCES_DARKFRAMESHOTS;shots !PREFERENCES_DARKFRAMETEMPLATES;templates !PREFERENCES_DAUB_LABEL;Use Daubechies D6 wavelets instead of D4 !PREFERENCES_DAUB_TOOLTIP;The Noise Reduction and Wavelet Levels tools use a Debauchies mother wavelet. If you choose D6 instead of D4 you increase the number of orthogonal Daubechies coefficients and probably increase quality of small-scale levels. There is no memory or processing time difference between the two. !PREFERENCES_DIRDARKFRAMES;Dark-frames directory +!PREFERENCES_DIRECTORIES;Directories !PREFERENCES_EDITORLAYOUT;Editor Layout !PREFERENCES_EXPAUT;Expert !PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar\n(de-select for low resolution display) -!PREFERENCES_FILMSIMULATION;Film Simulation -!PREFERENCES_FLATFIELD;Flat-Field !PREFERENCES_FLATFIELDFOUND;Found !PREFERENCES_FLATFIELDSDIR;Flat-fields directory !PREFERENCES_FLATFIELDSHOTS;shots @@ -1235,6 +1247,7 @@ TP_WBALANCE_TEMPERATURE;色溫 !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_RGBDTL_LABEL;Max number of threads for Noise Reduction and Wavelet Levels !PREFERENCES_RGBDTL_TOOLTIP;Leave the setting at "0" to automatically use as many threads as possible. The more threads run in parallel, the faster the computation. Refer to RawPedia for memory requirements. +!PREFERENCES_SAVE_TP_OPEN_NOW;Save tools collapsed/expanded state now !PREFERENCES_SELECTFONT;Select main font !PREFERENCES_SELECTFONT_COLPICKER;Select Color Picker's font !PREFERENCES_SERIALIZE_TIFF_READ;Tiff Read Settings @@ -1284,6 +1297,15 @@ TP_WBALANCE_TEMPERATURE;色溫 !PROGRESSBAR_PROCESSING_PROFILESAVED;Processing profile saved !PROGRESSBAR_SNAPSHOT_ADDED;Snapshot added !PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!QINFO_FRAMECOUNT;%2 frames +!QINFO_HDR;HDR / %2 frame(s) +!QINFO_PIXELSHIFT;Pixel Shift / %2 frame(s) +!SAMPLEFORMAT_0;Unknown data format +!SAMPLEFORMAT_1;Unsigned 8 bits +!SAMPLEFORMAT_2;Unsigned 16 bits +!SAMPLEFORMAT_4;LogLuv 24 bits +!SAMPLEFORMAT_8;LogLuv 32 bits +!SAMPLEFORMAT_16;32 bits floating point !SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists !SAVEDLG_FORCEFORMATOPTS;Force saving options !SAVEDLG_SUBSAMP;Subsampling @@ -1294,8 +1316,8 @@ TP_WBALANCE_TEMPERATURE;色溫 !SAVEDLG_TIFFUNCOMPRESSED;Uncompressed TIFF !SAVEDLG_WARNFILENAME;File will be named !SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. -!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the output profile. -!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate de rendering generated by the output profile of the ICM tool. Most useful for simulating printing outputs. +!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the Printer profile. +!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate the printer's output by using the Printer profile set in Preferences > Color Management. !THRESHOLDSELECTOR_B;Bottom !THRESHOLDSELECTOR_BL;Bottom-left !THRESHOLDSELECTOR_BR;Bottom-right @@ -1440,7 +1462,7 @@ TP_WBALANCE_TEMPERATURE;色溫 !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 Tint=1.\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\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504 !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_WBCAM;WB [RT+CAT02] + [output] @@ -1704,7 +1726,7 @@ TP_WBALANCE_TEMPERATURE;色溫 !TP_LENSGEOM_AUTOCROP;Auto-Crop !TP_LENSGEOM_FILL;Auto-fill !TP_LENSGEOM_LABEL;Lens / Geometry -!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_LABEL;Profiled Lens Correction !TP_LENSPROFILE_USECA;Chromatic aberration correction !TP_LENSPROFILE_USEDIST;Distortion correction !TP_LENSPROFILE_USEVIGN;Vignetting correction @@ -1926,6 +1948,9 @@ TP_WBALANCE_TEMPERATURE;色溫 !TP_SHARPENMICRO_LABEL;Microcontrast !TP_SHARPENMICRO_MATRIX;3×3 matrix instead of 5×5 !TP_SHARPENMICRO_UNIFORMITY;Uniformity +!TP_TM_FATTAL_AMOUNT;Amount +!TP_TM_FATTAL_LABEL;HDR Tone Mapping +!TP_TM_FATTAL_THRESHOLD;Threshold !TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift !TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH !TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones diff --git a/rtdata/languages/Czech b/rtdata/languages/Czech index 31b2255bb..29cf45b3d 100644 --- a/rtdata/languages/Czech +++ b/rtdata/languages/Czech @@ -993,7 +993,6 @@ PREFERENCES_D50;5000K PREFERENCES_D55;5500K PREFERENCES_D60;6000K PREFERENCES_D65;6500K -PREFERENCES_DARKFRAME;Tmavý snímek PREFERENCES_DARKFRAMEFOUND;Nalezeno PREFERENCES_DARKFRAMESHOTS;snímků PREFERENCES_DARKFRAMETEMPLATES;šablon @@ -1014,8 +1013,6 @@ PREFERENCES_EXTERNALEDITOR;Externí editor PREFERENCES_FBROWSEROPTS;Volby prohlížeče souborů / náhledů PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Jednořádková lišta nástrojů v prohlížeči souborů\n(vypněte na nízkých rozlišeních) PREFERENCES_FILEFORMAT;Formát souboru -PREFERENCES_FILMSIMULATION;Simulace filmu -PREFERENCES_FLATFIELD;Flat Field PREFERENCES_FLATFIELDFOUND;Nalezeno PREFERENCES_FLATFIELDSDIR;Složka Flat Field souborů PREFERENCES_FLATFIELDSHOTS;snímků @@ -2170,6 +2167,7 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !!!!!!!!!!!!!!!!!!!!!!!!! !DONT_SHOW_AGAIN;Don't show this message again. +!EXIFPANEL_SHOWALL;Show all !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. !HISTORY_MSG_476;CAM02 - Temp out !HISTORY_MSG_477;CAM02 - Green out @@ -2180,14 +2178,41 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !HISTORY_MSG_482;CAM02 - Green scene !HISTORY_MSG_483;CAM02 - Yb scene !HISTORY_MSG_484;CAM02 - Auto Yb scene +!HISTORY_MSG_485;Lens Correction +!HISTORY_MSG_486;Lens Correction - Camera +!HISTORY_MSG_487;Lens Correction - Lens +!HISTORY_MSG_488;HDR Tone Mapping +!HISTORY_MSG_489;HDR TM - Threshold +!HISTORY_MSG_490;HDR TM - Amount +!LENSPROFILE_CORRECTION_AUTOMATCH;Auto-matched correction parameters +!LENSPROFILE_CORRECTION_LCPFILE;LCP File +!LENSPROFILE_CORRECTION_MANUAL;Manual correction parameters +!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. +!MAIN_TOOLTIP_BACKCOLOR3;Background color of the preview: Middle grey\nShortcut: 9 +!PARTIALPASTE_TM_FATTAL;HDR Tone mapping +!PREFERENCES_AUTOSAVE_TP_OPEN;Automatically save tools collapsed/expanded\nstate before exiting !PREFERENCES_D50_OLD;5000K +!PREFERENCES_DIRECTORIES;Directories !PREFERENCES_GREY18_OLD;Yb=18 CIE L#50 !PREFERENCES_LANG;Language +!PREFERENCES_SAVE_TP_OPEN_NOW;Save tools collapsed/expanded state now !PREFERENCES_THEME;Theme +!QINFO_FRAMECOUNT;%2 frames +!QINFO_HDR;HDR / %2 frame(s) +!QINFO_PIXELSHIFT;Pixel Shift / %2 frame(s) +!SAMPLEFORMAT_0;Unknown data format +!SAMPLEFORMAT_1;Unsigned 8 bits +!SAMPLEFORMAT_2;Unsigned 16 bits +!SAMPLEFORMAT_4;LogLuv 24 bits +!SAMPLEFORMAT_8;LogLuv 32 bits +!SAMPLEFORMAT_16;32 bits floating point !TP_COLORAPP_FREE;Free temp+green + CAT02 + [output] !TP_COLORAPP_NEUTRAL;Reset !TP_COLORAPP_NEUTRAL_TIP;Reset all sliders checkbox and curves to their default values -!TP_COLORAPP_TEMP_TOOLTIP;To select an illuminant always Tint=1.\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\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504 !TP_COLORAPP_YB;Yb% (mean luminance) !TP_COLORAPP_YBSCENE;Yb% (mean luminance) !TP_COLORAPP_YBSCENE_TOOLTIP;if auto enable, Yb is calculated from the mean value of actual image luminance +!TP_TM_FATTAL_AMOUNT;Amount +!TP_TM_FATTAL_LABEL;HDR Tone Mapping +!TP_TM_FATTAL_THRESHOLD;Threshold diff --git a/rtdata/languages/Dansk b/rtdata/languages/Dansk index de3163d21..0b619b706 100644 --- a/rtdata/languages/Dansk +++ b/rtdata/languages/Dansk @@ -463,6 +463,7 @@ TP_WBALANCE_TEMPERATURE;Temperatur !EXIFFILTER_EXPOSURECOMPENSATION;Exposure compensation (EV) !EXIFFILTER_FILETYPE;File type !EXIFFILTER_METADATAFILTER;Enable metadata filters +!EXIFPANEL_SHOWALL;Show all !EXPORT_BYPASS;Processing steps to bypass !EXPORT_BYPASS_ALL;Select / Unselect All !EXPORT_BYPASS_DEFRINGE;Bypass Defringe @@ -585,7 +586,7 @@ TP_WBALANCE_TEMPERATURE;Temperatur !HISTORY_MSG_82;Profile changed !HISTORY_MSG_83;S/H - Sharp mask !HISTORY_MSG_84;Perspective correction -!HISTORY_MSG_85;LCP +!HISTORY_MSG_85;Lens Correction - LCP file !HISTORY_MSG_86;RGB Curves - Luminosity mode !HISTORY_MSG_87;Impulse Noise Reduction !HISTORY_MSG_88;Impulse NR threshold @@ -968,6 +969,12 @@ TP_WBALANCE_TEMPERATURE;Temperatur !HISTORY_MSG_482;CAM02 - Green scene !HISTORY_MSG_483;CAM02 - Yb scene !HISTORY_MSG_484;CAM02 - Auto Yb scene +!HISTORY_MSG_485;Lens Correction +!HISTORY_MSG_486;Lens Correction - Camera +!HISTORY_MSG_487;Lens Correction - Lens +!HISTORY_MSG_488;HDR Tone Mapping +!HISTORY_MSG_489;HDR TM - Threshold +!HISTORY_MSG_490;HDR TM - Amount !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider. !IPTCPANEL_CITYHINT;Enter the name of the city pictured in this image. @@ -994,6 +1001,10 @@ TP_WBALANCE_TEMPERATURE;Temperatur !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. +!LENSPROFILE_CORRECTION_AUTOMATCH;Auto-matched correction parameters +!LENSPROFILE_CORRECTION_LCPFILE;LCP File +!LENSPROFILE_CORRECTION_MANUAL;Manual correction parameters +!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. !MAIN_BUTTON_FULLSCREEN;Fullscreen !MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the next image relative to image opened in the Editor.\nShortcut: Shift-F4\n\nTo navigate to the next image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F4 !MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the previous image relative to image opened in the Editor.\nShortcut: Shift-F3\n\nTo navigate to the previous image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F3 @@ -1029,6 +1040,7 @@ TP_WBALANCE_TEMPERATURE;Temperatur !MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 9 !MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 !MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 9 +!MAIN_TOOLTIP_BACKCOLOR3;Background color of the preview: Middle grey\nShortcut: 9 !MAIN_TOOLTIP_BEFOREAFTERLOCK;Lock / Unlock the Before view\n\nLock: keep the Before view unchanged.\nUseful to evaluate the cumulative effect of multiple tools.\nAdditionally, comparisons can be made to any state in the History.\n\nUnlock: the Before view will follow the After view one step behind, showing the image before the effect of the currently used tool. !MAIN_TOOLTIP_PREVIEWB;Preview the Blue channel.\nShortcut: b !MAIN_TOOLTIP_PREVIEWFOCUSMASK;Preview the Focus Mask.\nShortcut: Shift-f\n\nMore accurate on images with shallow depth of field, low noise and at higher zoom levels.\n\nTo improve detection accuracy for noisy images evaluate at smaller zoom, about 10-30%. @@ -1079,7 +1091,7 @@ TP_WBALANCE_TEMPERATURE;Temperatur !PARTIALPASTE_HSVEQUALIZER;HSV equalizer !PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction !PARTIALPASTE_LABCURVE;L*a*b* adjustments -!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_LENSPROFILE;Profiled lens correction !PARTIALPASTE_PCVIGNETTE;Vignette filter !PARTIALPASTE_PERSPECTIVE;Perspective !PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter @@ -1099,11 +1111,12 @@ TP_WBALANCE_TEMPERATURE;Temperatur !PARTIALPASTE_RAW_FALSECOLOR;False color suppression !PARTIALPASTE_RAW_IMAGENUM;Sub-image !PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps -!PARTIALPASTE_RAW_PIXELSHIFT;PixelShift +!PARTIALPASTE_RAW_PIXELSHIFT;Pixel Shift !PARTIALPASTE_RETINEX;Retinex !PARTIALPASTE_RGBCURVES;RGB curves !PARTIALPASTE_SHARPENEDGE;Edges !PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_TM_FATTAL;HDR Tone mapping !PARTIALPASTE_VIBRANCE;Vibrance !PARTIALPASTE_WAVELETGROUP;Wavelet Levels !PREFERENCES_ADD;Add @@ -1113,6 +1126,7 @@ TP_WBALANCE_TEMPERATURE;Temperatur !PREFERENCES_AUTLISVLOW;None !PREFERENCES_AUTLOW;Low !PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +!PREFERENCES_AUTOSAVE_TP_OPEN;Automatically save tools collapsed/expanded\nstate before exiting !PREFERENCES_AUTSTD;Standard !PREFERENCES_BATCH_PROCESSING;Batch Processing !PREFERENCES_BEHADDALL;All to 'Add' @@ -1146,18 +1160,16 @@ TP_WBALANCE_TEMPERATURE;Temperatur !PREFERENCES_D55;5500K !PREFERENCES_D60;6000K !PREFERENCES_D65;6500K -!PREFERENCES_DARKFRAME;Dark-Frame !PREFERENCES_DARKFRAMEFOUND;Found !PREFERENCES_DARKFRAMESHOTS;shots !PREFERENCES_DARKFRAMETEMPLATES;templates !PREFERENCES_DAUB_LABEL;Use Daubechies D6 wavelets instead of D4 !PREFERENCES_DAUB_TOOLTIP;The Noise Reduction and Wavelet Levels tools use a Debauchies mother wavelet. If you choose D6 instead of D4 you increase the number of orthogonal Daubechies coefficients and probably increase quality of small-scale levels. There is no memory or processing time difference between the two. !PREFERENCES_DIRDARKFRAMES;Dark-frames directory +!PREFERENCES_DIRECTORIES;Directories !PREFERENCES_EDITORLAYOUT;Editor Layout !PREFERENCES_EXPAUT;Expert !PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar\n(de-select for low resolution display) -!PREFERENCES_FILMSIMULATION;Film Simulation -!PREFERENCES_FLATFIELD;Flat-Field !PREFERENCES_FLATFIELDFOUND;Found !PREFERENCES_FLATFIELDSDIR;Flat-fields directory !PREFERENCES_FLATFIELDSHOTS;shots @@ -1233,6 +1245,7 @@ TP_WBALANCE_TEMPERATURE;Temperatur !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_RGBDTL_LABEL;Max number of threads for Noise Reduction and Wavelet Levels !PREFERENCES_RGBDTL_TOOLTIP;Leave the setting at "0" to automatically use as many threads as possible. The more threads run in parallel, the faster the computation. Refer to RawPedia for memory requirements. +!PREFERENCES_SAVE_TP_OPEN_NOW;Save tools collapsed/expanded state now !PREFERENCES_SELECTFONT;Select main font !PREFERENCES_SELECTFONT_COLPICKER;Select Color Picker's font !PREFERENCES_SERIALIZE_TIFF_READ;Tiff Read Settings @@ -1282,6 +1295,15 @@ TP_WBALANCE_TEMPERATURE;Temperatur !PROGRESSBAR_PROCESSING_PROFILESAVED;Processing profile saved !PROGRESSBAR_SNAPSHOT_ADDED;Snapshot added !PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!QINFO_FRAMECOUNT;%2 frames +!QINFO_HDR;HDR / %2 frame(s) +!QINFO_PIXELSHIFT;Pixel Shift / %2 frame(s) +!SAMPLEFORMAT_0;Unknown data format +!SAMPLEFORMAT_1;Unsigned 8 bits +!SAMPLEFORMAT_2;Unsigned 16 bits +!SAMPLEFORMAT_4;LogLuv 24 bits +!SAMPLEFORMAT_8;LogLuv 32 bits +!SAMPLEFORMAT_16;32 bits floating point !SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists !SAVEDLG_FORCEFORMATOPTS;Force saving options !SAVEDLG_SUBSAMP;Subsampling @@ -1292,8 +1314,8 @@ TP_WBALANCE_TEMPERATURE;Temperatur !SAVEDLG_TIFFUNCOMPRESSED;Uncompressed TIFF !SAVEDLG_WARNFILENAME;File will be named !SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. -!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the output profile. -!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate de rendering generated by the output profile of the ICM tool. Most useful for simulating printing outputs. +!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the Printer profile. +!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate the printer's output by using the Printer profile set in Preferences > Color Management. !THRESHOLDSELECTOR_B;Bottom !THRESHOLDSELECTOR_BL;Bottom-left !THRESHOLDSELECTOR_BR;Bottom-right @@ -1438,7 +1460,7 @@ TP_WBALANCE_TEMPERATURE;Temperatur !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 Tint=1.\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\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504 !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_WBCAM;WB [RT+CAT02] + [output] @@ -1702,7 +1724,7 @@ TP_WBALANCE_TEMPERATURE;Temperatur !TP_LENSGEOM_AUTOCROP;Auto-Crop !TP_LENSGEOM_FILL;Auto-fill !TP_LENSGEOM_LABEL;Lens / Geometry -!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_LABEL;Profiled Lens Correction !TP_LENSPROFILE_USECA;Chromatic aberration correction !TP_LENSPROFILE_USEDIST;Distortion correction !TP_LENSPROFILE_USEVIGN;Vignetting correction @@ -1925,6 +1947,9 @@ TP_WBALANCE_TEMPERATURE;Temperatur !TP_SHARPENMICRO_LABEL;Microcontrast !TP_SHARPENMICRO_MATRIX;3×3 matrix instead of 5×5 !TP_SHARPENMICRO_UNIFORMITY;Uniformity +!TP_TM_FATTAL_AMOUNT;Amount +!TP_TM_FATTAL_LABEL;HDR Tone Mapping +!TP_TM_FATTAL_THRESHOLD;Threshold !TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift !TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH !TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones diff --git a/rtdata/languages/Deutsch b/rtdata/languages/Deutsch index 346cdf264..cda1faa42 100644 --- a/rtdata/languages/Deutsch +++ b/rtdata/languages/Deutsch @@ -42,6 +42,9 @@ #41 03.05.2017 Erweiterung/Korrekturen (TooWaBoo) RT 5.0 r1 #42 13.05.2017 Erweiterung (TooWaBoo) RT 5.0 r1 #43 21.07.2017 Erweiterung (TooWaBoo) RT 5.1 +#44 21.09.2017 Erweiterung (TooWaBoo) RT 5.2 +#45 15.10.2017 Erweiterung (TooWaBoo) RT 5.3 +#46 18.10.2017 Erweiterung (TooWaBoo) RT 5.3 ABOUT_TAB_BUILD;Version ABOUT_TAB_CREDITS;Danksagungen @@ -77,6 +80,7 @@ CURVEEDITOR_TOOLTIPPASTE;Kurve aus Zwischenablage einfügen CURVEEDITOR_TOOLTIPSAVE;Kurve speichern CURVEEDITOR_TYPE;Typ: DIRBROWSER_FOLDERS;Ordner +DONT_SHOW_AGAIN;Meldung nicht mehr anzeigen. DYNPROFILEEDITOR_DELETE;Löschen DYNPROFILEEDITOR_EDIT;Ändern DYNPROFILEEDITOR_EDIT_RULE;Profilregel ändern @@ -111,6 +115,7 @@ EXIFPANEL_RESET;Zurücksetzen EXIFPANEL_RESETALL;Alle zurücksetzen EXIFPANEL_RESETALLHINT;Alle Attribute auf die ursprünglichen Werte zurücksetzen EXIFPANEL_RESETHINT;Gewählte Attribute auf die ursprünglichen Werte zurücksetzen +EXIFPANEL_SHOWALL;Alle anzeigen EXIFPANEL_SUBDIRECTORY;Unterverzeichnis EXPORT_BYPASS;Verarbeitungsschritte überspringen EXPORT_BYPASS_ALL;Alle/Keine auswählen @@ -275,6 +280,7 @@ GENERAL_PORTRAIT;Portrait GENERAL_SAVE;Speichern GENERAL_UNCHANGED;(Unverändert) GENERAL_WARNING;Warnung +GIMP_PLUGIN_INFO;Willkommen zum RawTherapee GIMP-Plugin!\nNach den Änderungen bitte das RawTherapee-Fenster schließen.\nDas Bild wird dann automatisch in GIMP importiert. HISTOGRAM_TOOLTIP_B;Blau-Histogramm ein-/ausblenden HISTOGRAM_TOOLTIP_BAR;RGB-Anzeigeleiste ein-/ausblenden\n\nZum Fixieren/Lösen der Anzeige muss mit der\nrechten Maustaste ins Bildfenster geklickt werden. HISTOGRAM_TOOLTIP_CHRO;Chromatizität-Histogramm ein/ausblenden @@ -463,8 +469,8 @@ HISTORY_MSG_173;(Rauschreduzierung)\nLuminanzdetails HISTORY_MSG_174;(CIECAM02) HISTORY_MSG_175;(CIECAM02) - Szene\nCAT02-Adaptation HISTORY_MSG_176;(CIECAM02)\nBetrachtungsbed.\nUmgebung -HISTORY_MSG_177;(CIECAM02) - Szene\nLeuchtstärke -HISTORY_MSG_178;(CIECAM02)\nBetrachtungsbed.\nLeuchtstärke +HISTORY_MSG_177;(CIECAM02) - Szene\nLuminanz +HISTORY_MSG_178;(CIECAM02)\nBetrachtungsbed.\nLuminanz HISTORY_MSG_179;(CIECAM02) - Szene\nWeißpunktmodell HISTORY_MSG_180;(CIECAM02) - Helligkeit (J) HISTORY_MSG_181;(CIECAM02) - Buntheit (H) @@ -492,7 +498,7 @@ HISTORY_MSG_202;(Rauschreduzierung)\nDelta-Chrominanz\nBlau / Gelb HISTORY_MSG_203;(Rauschreduzierung)\nMethode HISTORY_MSG_204;(Sensor-Matrix)\nFarbinterpolation\nLMMSE-Verbesserung HISTORY_MSG_205;(CIECAM02)\nBetrachtungsbed.\nHot / Bad-Pixelfilter -HISTORY_MSG_206;(CIECAM02) - Szene\nAuto-Leuchtstärke +HISTORY_MSG_206;(CIECAM02) - Szene\nAuto-Luminanz HISTORY_MSG_207;(Farbsaum entfernen)\nFarbtonkurve HISTORY_MSG_208;(Weißabgleich)\nBlau / Rot-Korrektur HISTORY_MSG_210;(Grauverlaufsfilter)\nRotationswinkel @@ -731,36 +737,32 @@ HISTORY_MSG_442;(Retinex) - Einstellungen\nTransmission - Skalierung HISTORY_MSG_443;(Farbmanagement)\nAusgabeprofil\nSchwarzpunkt-Kompensation HISTORY_MSG_444;(Weißabgleich)\nAWB-Temperatur-Korrektur HISTORY_MSG_445;(Sensor-Matrix)\nFarbinterpolation\nUnterbild -HISTORY_MSG_446;EvPixelShiftMotion -HISTORY_MSG_447;EvPixelShiftMotionCorrection -HISTORY_MSG_448;EvPixelShiftStddevFactorGreen HISTORY_MSG_449;(Sensor-Matrix)\nFarbinterpolation\nISO-Anpassung -HISTORY_MSG_450;EvPixelShiftNreadIso -HISTORY_MSG_451;EvPixelShiftPrnu HISTORY_MSG_452;(Sensor-Matrix)\nFarbinterpolation\nBewegungsmaske\nanzeigen HISTORY_MSG_453;(Sensor-Matrix)\nFarbinterpolation\nNur Maske anzeigen -HISTORY_MSG_454;EvPixelShiftAutomatic -HISTORY_MSG_455;EvPixelShiftNonGreenHorizontal -HISTORY_MSG_456;EvPixelShiftNonGreenVertical HISTORY_MSG_457;(Sensor-Matrix)\nFarbinterpolation\nBewegung im Rot/Blau-\nKanal erkennen -HISTORY_MSG_458;EvPixelShiftStddevFactorRed -HISTORY_MSG_459;EvPixelShiftStddevFactorBlue -HISTORY_MSG_460;EvPixelShiftGreenAmaze -HISTORY_MSG_461;EvPixelShiftNonGreenAmaze HISTORY_MSG_462;(Sensor-Matrix)\nFarbinterpolation\nBewegung im Grün-\nKanal erkennen -HISTORY_MSG_463;EvPixelShiftRedBlueWeight HISTORY_MSG_464;(Sensor-Matrix)\nFarbinterpolation\nUnschärfebewegungsmaske HISTORY_MSG_465;(Sensor-Matrix)\nFarbinterpolation\nUnschärferadius -HISTORY_MSG_466;EvPixelShiftSum -HISTORY_MSG_467;EvPixelShiftExp0 HISTORY_MSG_468;(Sensor-Matrix)\nFarbinterpolation\nLücken in der Bewegungs-\nmaske erkennen HISTORY_MSG_469;(Sensor-Matrix)\nFarbinterpolation\nMedian -HISTORY_MSG_470;EvPixelShiftMedian3 HISTORY_MSG_471;(Sensor-Matrix)\nFarbinterpolation\nBewegungskorrektur HISTORY_MSG_472;(Sensor-Matrix)\nFarbinterpolation\nWeicher Übergang HISTORY_MSG_473;(Sensor-Matrix)\nFarbinterpolation\nLMMSE für Bewegungs-\nteile verwenden HISTORY_MSG_474;(Sensor-Matrix)\nFarbinterpolation\nFrame-Helligkeit angleichen HISTORY_MSG_475;(Sensor-Matrix)\nFarbinterpolation)\nAusgleich pro Kanal +HISTORY_MSG_476;(CIECAM02)\nBetrachtungsbed.\nFarbtemperatur +HISTORY_MSG_477;(CIECAM02)\nBetrachtungsbed.\nTönung +HISTORY_MSG_478;(CIECAM02)\nBetrachtungsbed.\nYb% (Ø Luminanz) +HISTORY_MSG_479;(CIECAM02)\nBetrachtungsbed.\nCAT02 Adaptation +HISTORY_MSG_480;(CIECAM02)\nBetrachtungsbed.\nAuto CAT02 Adaptation +HISTORY_MSG_481;(CIECAM02) - Szene\nFarbtemperatur +HISTORY_MSG_482;(CIECAM02) - Szene\nTönung +HISTORY_MSG_483;(CIECAM02) - Szene\nYb% (Ø Luminanz) +HISTORY_MSG_484;(CIECAM02) - Szene\nAuto Yb% +HISTORY_MSG_485;(Objektivkorrektur)\nProfil +HISTORY_MSG_486;(Objektivkorrektur)\nProfil - Kamera +HISTORY_MSG_487;(Objektivkorrektur)\nProfil - Objektiv HISTORY_NEWSNAPSHOT;Hinzufügen HISTORY_NEWSNAPSHOT_TOOLTIP;Taste: Alt + s HISTORY_SNAPSHOT;Schnappschuss @@ -807,6 +809,10 @@ IPTCPANEL_TITLE;Titel IPTCPANEL_TITLEHINT;Geben Sie einen kurzen lesbaren Namen\nfür das Bild ein, z.B. den Dateinamen. IPTCPANEL_TRANSREFERENCE;Verarbeitungs-ID IPTCPANEL_TRANSREFERENCEHINT;Geben Sie eine Kennung zur Kontrolle oder\nVerfolgung des Arbeitsablaufes ein. +LENSPROFILE_CORRECTION_AUTOMATCH;Automatisch (Lensfun) +LENSPROFILE_CORRECTION_LCPFILE;LCP-Datei +LENSPROFILE_CORRECTION_MANUAL;Benutzerdefiniert (Lensfun) +LENSPROFILE_LENS_WARNING;Warnung: Der Cropfaktor des Profils entspricht nicht dem des Objektivs.\nDies kann zu einem fehlerhaften Ergebnis führen. MAIN_BUTTON_FULLSCREEN;Vollbild\nTaste: F11 MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigiert zum nächsten Miniaturbild in der\nDateiverwaltung oder Filmstreifen bezogen\nauf das ausgewählte Miniaturbild.\nTaste: F4\n\nNavigiert zum nächsten Miniaturbild in der\nDateiverwaltung oder Filmstreifen bezogen\nauf auf das im Editor geöffnete Bild.\nTaste: Umschalt + F4 MAIN_BUTTON_NAVPREV_TOOLTIP;Navigiert zum vorherigen Miniaturbild in der\nDateiverwaltung oder Filmstreifen bezogen\nauf das ausgewählte Miniaturbild.\nTaste: F3\n\nNavigiert zum vorherigen Miniaturbild in der\nDateiverwaltung oder Filmstreifen bezogen\nauf auf das im Editor geöffnete Bild.\nTaste: Umschalt + F3 @@ -865,6 +871,7 @@ MAIN_TAB_WAVELET_TOOLTIP;Taste: Alt + w MAIN_TOOLTIP_BACKCOLOR0;Hintergrundfarbe der Vorschau basierend auf dem: Oberflächendesign\nTaste: 9 MAIN_TOOLTIP_BACKCOLOR1;Hintergrundfarbe der Vorschau: Schwarz\nTaste: 9 MAIN_TOOLTIP_BACKCOLOR2;Hintergrundfarbe der Vorschau: Weiß\nTaste: 9 +MAIN_TOOLTIP_BACKCOLOR3;Hintergrundfarbe der Vorschau: Mittleres Grau\nTaste: 9 MAIN_TOOLTIP_BEFOREAFTERLOCK;Vorher-Ansicht: Sperren / Entsperren\n\nGesperrt: Friert die Vorher-Ansicht ein, so\ndass sich die Gesamtwirkung mehrerer\nBearbeitungsschritte beurteilen lässt.\n\nEntsperrt: Die Vorher-Ansicht hinkt dem\naktuellen Bild immer einen Bearbeitungs-\nschritt hinterher. MAIN_TOOLTIP_HIDEHP;Linkes Bedienfeld ein-/ausblenden\nTaste: l MAIN_TOOLTIP_INDCLIPPEDH;Anzeige zu heller Bereiche ein-/ausschalten\nTaste: < @@ -974,6 +981,7 @@ PREFERENCES_AUTLISSTD;Hoch PREFERENCES_AUTLISVLOW;Keine PREFERENCES_AUTLOW;Niedrig PREFERENCES_AUTOMONPROFILE;Automatisch das für den aktuellen Monitor festgelegte Profil verwenden. +PREFERENCES_AUTOSAVE_TP_OPEN;Werkzeugstatus vor dem Beenden automatisch speichern PREFERENCES_AUTSTD;Standard PREFERENCES_BATCH_PROCESSING;Stapelverarbeitung PREFERENCES_BEHADDALL;Alle hinzufügen @@ -1010,10 +1018,10 @@ PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;Tag-ID PREFERENCES_CUSTPROFBUILDPATH;Anwendungspfad PREFERENCES_CUTOVERLAYBRUSH;Farbe/Transparenz für Schnittmaske PREFERENCES_D50;5000K +PREFERENCES_D50_OLD;5000K PREFERENCES_D55;5500K PREFERENCES_D60;6000K PREFERENCES_D65;6500K -PREFERENCES_DARKFRAME;Dunkelbild PREFERENCES_DARKFRAMEFOUND;Gefunden PREFERENCES_DARKFRAMESHOTS;Aufnahmen PREFERENCES_DARKFRAMETEMPLATES;Vorlagen @@ -1022,6 +1030,7 @@ PREFERENCES_DATEFORMATHINT;Die folgenden Variablen können verwendet werden:\n[ TP_COARSETRAF_TOOLTIP_ROTRIGHT;Nach rechts drehen\nTaste: ] TP_COARSETRAF_TOOLTIP_VFLIP;Vertikal spiegeln -TP_COLORAPP_ADAPTSCENE;Leuchtstärke (cd/m²) +TP_COLORAPP_ADAPTSCENE;Luminanz (cd/m²) TP_COLORAPP_ADAPTSCENE_TOOLTIP;Absolute Luminanz der Szenenleuchstärket\n(normalerweise 2000cd/m²) -TP_COLORAPP_ADAPTVIEWING;Leuchtstärke (cd/m²) +TP_COLORAPP_ADAPTVIEWING;Luminanz (cd/m²) TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Absolute Luminanz der Betrachtungsumgebung\n(normalerweise 16cd/m²) TP_COLORAPP_ADAP_AUTO_TOOLTIP;Wenn aktiviert (empfohlen), werden die optimalen\nWerte aus den Exif-Daten automatisch berechnet. TP_COLORAPP_ALGO;Algorithmus @@ -1358,6 +1378,7 @@ TP_COLORAPP_DATACIE;CIECAM02-Ausgabe-Histogramm in\nKurven anzeigen TP_COLORAPP_DATACIE_TOOLTIP;Wenn aktiviert, zeigen die Histogramme\nder CIECAM02-Kurven die angenäherten\nWerte/Bereiche für J oder Q und C, S oder M\nNACH den CIECAM02-Anpassungen an. Das\nbetrifft nicht das Haupt-Histogramm.\n\nWenn deaktiviert, zeigen die Histogramme\nder CIECAM02-Kurven die L*a*b*-Werte\nVOR den CIECAM02-Anpassungen an. TP_COLORAPP_DEGREE_AUTO_TOOLTIP;Wenn aktiviert (empfohlen), wird ein optimaler\nWert berechnet, der von CAT02 und CIECAM02\nverwendet wird.\nUm den Wert manuell zu setzen, muss die Option\ndeaktiviert sein (Werte über 64 sind empfohlen). TP_COLORAPP_DEGREE_TOOLTIP;Umfang der “CIE Chromatic Adaptation Transform 2002“ +TP_COLORAPP_FREE;Farbtemperatur + Tönung + CAT02 + [Ausgabe] TP_COLORAPP_GAMUT;Gamutkontrolle (L*a*b*) TP_COLORAPP_GAMUT_TOOLTIP;Gamutkontrolle im L*a*b*-Modus erlauben. TP_COLORAPP_HUE;Farbton (H) @@ -1370,6 +1391,8 @@ TP_COLORAPP_LIGHT;Helligkeit (J) TP_COLORAPP_LIGHT_TOOLTIP;Helligkeit in CIECAM02 unterscheidet sich\nvon L*a*b* und RGB Helligkeit TP_COLORAPP_MODEL;Weißpunktmodell TP_COLORAPP_MODEL_TOOLTIP;Weißabgleich [RT] + [Ausgabe]:\nRT's Weißabgleich wird für die Szene verwendet,\nCIECAM02 auf D50 gesetzt und der Weißabgleich\ndes Ausgabegerätes kann unter:\nEinstellungen > Farb-Management\neingestellt werden.\n\nWeißabgleich [RT+CAT02] + [Ausgabe]:\nRT's Weißabgleich wird für CAT02 verwendet und\nder Weißabgleich des Ausgabegerätes kann unter\nEinstellungen > Farb-Management\neingestellt werden. +TP_COLORAPP_NEUTRAL;Zurücksetzen +TP_COLORAPP_NEUTRAL_TIP;Setzt alle CIECAM02-Parameter auf Vorgabewerte zurück. TP_COLORAPP_RSTPRO;Hautfarbtöne schützen TP_COLORAPP_RSTPRO_TOOLTIP;Hautfarbtöne schützen\nWirkt sich auf Regler und Kurven aus. TP_COLORAPP_SHARPCIE;--unused-- @@ -1390,10 +1413,14 @@ TP_COLORAPP_TCMODE_LABEL2;Tonwertkurve 2 Modus TP_COLORAPP_TCMODE_LABEL3;Farbkurve Modus TP_COLORAPP_TCMODE_LIGHTNESS;Helligkeit (J) TP_COLORAPP_TCMODE_SATUR;Sättigung (S) +TP_COLORAPP_TEMP_TOOLTIP;Um eine Farbtemperatur auszuwählen\nsetzen Sie die Tönung immer auf "1".\nA Temp=2856\nD50 Temp=5003\nD55 Temp=5503\nD65 Temp=6504\nD75 Temp=7504 TP_COLORAPP_TONECIE;Dynamikkompression mittels\nCIECAM02-Helligkeit (Q) TP_COLORAPP_TONECIE_TOOLTIP;Wenn diese Option ausgeschaltet ist, wird die Dynamikkompression im L*a*b*-Farbraum durchgeführt.\nWenn die Option eingeschaltet ist, wird CIECAM02 für die Dynamikkompression verwendet. Das Werkzeug Dynamikkompression muss aktiviert sein, damit diese Option berücksichtigt wird. TP_COLORAPP_WBCAM;[RT+CAT02] + [Ausgabe] TP_COLORAPP_WBRT;[RT] + [Ausgabe] +TP_COLORAPP_YB;Yb% (Ø Luminanz) +TP_COLORAPP_YBSCENE;Yb% (Ø Luminanz) +TP_COLORAPP_YBSCENE_TOOLTIP;Wenn aktiviert, wird der Durchschnittswert der Luminanz berechnet. TP_COLORTONING_AB;o C/L TP_COLORTONING_AUTOSAT;Automatisch TP_COLORTONING_BALANCE;Farbausgleich @@ -2189,25 +2216,10 @@ ZOOMPANEL_ZOOMOUT;Herauszoomen\nTaste: - ! Untranslated keys follow; remove the ! prefix after an entry is translated. !!!!!!!!!!!!!!!!!!!!!!!!! -!DONT_SHOW_AGAIN;Don't show this message again. -!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. -!HISTORY_MSG_476;CAM02 - Temp out -!HISTORY_MSG_477;CAM02 - Green out -!HISTORY_MSG_478;CAM02 - Yb out -!HISTORY_MSG_479;CAM02 - CAT02 adaptation out -!HISTORY_MSG_480;CAM02 - Automatic CAT02 out -!HISTORY_MSG_481;CAM02 - Temp scene -!HISTORY_MSG_482;CAM02 - Green scene -!HISTORY_MSG_483;CAM02 - Yb scene -!HISTORY_MSG_484;CAM02 - Auto Yb scene -!PREFERENCES_D50_OLD;5000K -!PREFERENCES_GREY18_OLD;Yb=18 CIE L#50 -!PREFERENCES_LANG;Language -!PREFERENCES_THEME;Theme -!TP_COLORAPP_FREE;Free temp+green + CAT02 + [output] -!TP_COLORAPP_NEUTRAL;Reset -!TP_COLORAPP_NEUTRAL_TIP;Reset all sliders checkbox and curves to their default values -!TP_COLORAPP_TEMP_TOOLTIP;To select an illuminant always Tint=1.\nA temp=2856\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504 -!TP_COLORAPP_YB;Yb% (mean luminance) -!TP_COLORAPP_YBSCENE;Yb% (mean luminance) -!TP_COLORAPP_YBSCENE_TOOLTIP;if auto enable, Yb is calculated from the mean value of actual image luminance +!HISTORY_MSG_488;HDR Tone Mapping +!HISTORY_MSG_489;HDR TM - Threshold +!HISTORY_MSG_490;HDR TM - Amount +!PARTIALPASTE_TM_FATTAL;HDR Tone mapping +!TP_TM_FATTAL_AMOUNT;Amount +!TP_TM_FATTAL_LABEL;HDR Tone Mapping +!TP_TM_FATTAL_THRESHOLD;Threshold diff --git a/rtdata/languages/English (UK) b/rtdata/languages/English (UK) index 85d44e3ea..e4bbcacd8 100644 --- a/rtdata/languages/English (UK) +++ b/rtdata/languages/English (UK) @@ -25,6 +25,7 @@ MAIN_TAB_COLOR;Colour MAIN_TOOLTIP_BACKCOLOR0;Background colour of the preview: Theme-based\nShortcut: 9 MAIN_TOOLTIP_BACKCOLOR1;Background colour of the preview: Black\nShortcut: 9 MAIN_TOOLTIP_BACKCOLOR2;Background colour of the preview: White\nShortcut: 9 +MAIN_TOOLTIP_BACKCOLOR3;Background colour of the preview: Middle grey\nShortcut: 9 PARTIALPASTE_COLORGROUP;Colour Related Settings PARTIALPASTE_COLORTONING;Colour toning PARTIALPASTE_ICMSETTINGS;Colour management settings @@ -41,7 +42,8 @@ PREFERENCES_NAVGUIDEBRUSH;Navigator guide colour PREFERENCES_PRTPROFILE;Colour profile PREFERENCES_SELECTFONT_COLPICKER;Select Colour Picker's font PREFERENCES_TAB_COLORMGR;Colour Management -SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colours from the output profile. +SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colours from the Printer profile. +SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate the printer's output by using the Printer profile set in Preferences > Colour Management. TOOLBAR_TOOLTIP_COLORPICKER;Lockable Colour Picker\n\nWhen enabled:\nClick in the preview with left mouse button to add a colour picker\nDrag it around while pressing the left mouse button\nDelete the colour picker with a right mouse button click\nDelete all colour pickers with Shift + Right mouse button click\nRight click away from any colour picker to go back to the Hand tool TOOLBAR_TOOLTIP_STRAIGHTEN;Straighten / fine rotation.\nShortcut: s\n\nIndicate the vertical or horizontal by drawing a guide line over the image preview. Angle of rotation will be shown next to the guide line. Centre of rotation is the geometrical centre of the image. TP_BWMIX_CC_ENABLED;Adjust complementary colour @@ -175,6 +177,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !EXIFPANEL_RESETALL;Reset All !EXIFPANEL_RESETALLHINT;Reset all tags to their original values. !EXIFPANEL_RESETHINT;Reset the selected tags to their original values. +!EXIFPANEL_SHOWALL;Show all !EXIFPANEL_SUBDIRECTORY;Subdirectory !EXPORT_BYPASS;Processing steps to bypass !EXPORT_BYPASS_ALL;Select / Unselect All @@ -380,9 +383,9 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !HISTORY_MSG_31;RLD - Amount !HISTORY_MSG_32;RLD - Damping !HISTORY_MSG_33;RLD - Iterations -!HISTORY_MSG_34;LCP distortion correction -!HISTORY_MSG_35;LCP vignetting correction -!HISTORY_MSG_36;LCP CA correction +!HISTORY_MSG_34;Lens Correction - Distortion +!HISTORY_MSG_35;Lens Correction - Vignetting +!HISTORY_MSG_36;Lens Correction - CA !HISTORY_MSG_37;Exposure - Auto levels !HISTORY_MSG_38;White Balance - Method !HISTORY_MSG_39;WB - Temperature @@ -427,7 +430,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !HISTORY_MSG_82;Profile changed !HISTORY_MSG_83;S/H - Sharp mask !HISTORY_MSG_84;Perspective correction -!HISTORY_MSG_85;LCP +!HISTORY_MSG_85;Lens Correction - LCP file !HISTORY_MSG_86;RGB Curves - Luminosity mode !HISTORY_MSG_87;Impulse Noise Reduction !HISTORY_MSG_88;Impulse NR threshold @@ -796,6 +799,12 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !HISTORY_MSG_482;CAM02 - Green scene !HISTORY_MSG_483;CAM02 - Yb scene !HISTORY_MSG_484;CAM02 - Auto Yb scene +!HISTORY_MSG_485;Lens Correction +!HISTORY_MSG_486;Lens Correction - Camera +!HISTORY_MSG_487;Lens Correction - Lens +!HISTORY_MSG_488;HDR Tone Mapping +!HISTORY_MSG_489;HDR TM - Threshold +!HISTORY_MSG_490;HDR TM - Amount !HISTORY_NEWSNAPSHOT;Add !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !HISTORY_SNAPSHOT;Snapshot @@ -842,6 +851,10 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !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. +!LENSPROFILE_CORRECTION_AUTOMATCH;Auto-matched correction parameters +!LENSPROFILE_CORRECTION_LCPFILE;LCP File +!LENSPROFILE_CORRECTION_MANUAL;Manual correction parameters +!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. !MAIN_BUTTON_FULLSCREEN;Fullscreen !MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the next image relative to image opened in the Editor.\nShortcut: Shift-F4\n\nTo navigate to the next image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F4 !MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the previous image relative to image opened in the Editor.\nShortcut: Shift-F3\n\nTo navigate to the previous image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F3 @@ -960,7 +973,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !PARTIALPASTE_IPTCINFO;IPTC !PARTIALPASTE_LABCURVE;L*a*b* adjustments !PARTIALPASTE_LENSGROUP;Lens Related Settings -!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_LENSPROFILE;Profiled lens correction !PARTIALPASTE_METAGROUP;Metadata !PARTIALPASTE_PCVIGNETTE;Vignette filter !PARTIALPASTE_PERSPECTIVE;Perspective @@ -980,7 +993,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !PARTIALPASTE_RAW_DMETHOD;Demosaic method !PARTIALPASTE_RAW_IMAGENUM;Sub-image !PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps -!PARTIALPASTE_RAW_PIXELSHIFT;PixelShift +!PARTIALPASTE_RAW_PIXELSHIFT;Pixel Shift !PARTIALPASTE_RESIZE;Resize !PARTIALPASTE_RETINEX;Retinex !PARTIALPASTE_RGBCURVES;RGB curves @@ -989,6 +1002,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !PARTIALPASTE_SHARPENEDGE;Edges !PARTIALPASTE_SHARPENING;Sharpening (USM/RL) !PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_TM_FATTAL;HDR Tone mapping !PARTIALPASTE_VIBRANCE;Vibrance !PARTIALPASTE_VIGNETTING;Vignetting correction !PARTIALPASTE_WAVELETGROUP;Wavelet Levels @@ -1000,6 +1014,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !PREFERENCES_AUTLISSTD;High !PREFERENCES_AUTLISVLOW;None !PREFERENCES_AUTLOW;Low +!PREFERENCES_AUTOSAVE_TP_OPEN;Automatically save tools collapsed/expanded\nstate before exiting !PREFERENCES_AUTSTD;Standard !PREFERENCES_BATCH_PROCESSING;Batch Processing !PREFERENCES_BEHADDALL;All to 'Add' @@ -1038,7 +1053,6 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !PREFERENCES_D55;5500K !PREFERENCES_D60;6000K !PREFERENCES_D65;6500K -!PREFERENCES_DARKFRAME;Dark-Frame !PREFERENCES_DARKFRAMEFOUND;Found !PREFERENCES_DARKFRAMESHOTS;shots !PREFERENCES_DARKFRAMETEMPLATES;templates @@ -1047,6 +1061,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !PREFERENCES_DAUB_LABEL;Use Daubechies D6 wavelets instead of D4 !PREFERENCES_DAUB_TOOLTIP;The Noise Reduction and Wavelet Levels tools use a Debauchies mother wavelet. If you choose D6 instead of D4 you increase the number of orthogonal Daubechies coefficients and probably increase quality of small-scale levels. There is no memory or processing time difference between the two. !PREFERENCES_DIRDARKFRAMES;Dark-frames directory +!PREFERENCES_DIRECTORIES;Directories !PREFERENCES_DIRHOME;Home directory !PREFERENCES_DIRLAST;Last visited directory !PREFERENCES_DIROTHER;Other @@ -1059,8 +1074,6 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !PREFERENCES_FBROWSEROPTS;File Browser / Thumbnail Options !PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar\n(de-select for low resolution display) !PREFERENCES_FILEFORMAT;File format -!PREFERENCES_FILMSIMULATION;Film Simulation -!PREFERENCES_FLATFIELD;Flat-Field !PREFERENCES_FLATFIELDFOUND;Found !PREFERENCES_FLATFIELDSDIR;Flat-fields directory !PREFERENCES_FLATFIELDSHOTS;shots @@ -1155,6 +1168,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !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_RGBDTL_LABEL;Max number of threads for Noise Reduction and Wavelet Levels !PREFERENCES_RGBDTL_TOOLTIP;Leave the setting at "0" to automatically use as many threads as possible. The more threads run in parallel, the faster the computation. Refer to RawPedia for memory requirements. +!PREFERENCES_SAVE_TP_OPEN_NOW;Save tools collapsed/expanded state now !PREFERENCES_SELECTFONT;Select main font !PREFERENCES_SELECTLANG;Select language !PREFERENCES_SELECTTHEME;Select theme @@ -1231,13 +1245,21 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !PROGRESSBAR_SAVETIFF;Saving TIFF file... !PROGRESSBAR_SNAPSHOT_ADDED;Snapshot added !PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!QINFO_FRAMECOUNT;%2 frames +!QINFO_HDR;HDR / %2 frame(s) !QINFO_ISO;ISO !QINFO_NOEXIF;Exif data not available. +!QINFO_PIXELSHIFT;Pixel Shift / %2 frame(s) +!SAMPLEFORMAT_0;Unknown data format +!SAMPLEFORMAT_1;Unsigned 8 bits +!SAMPLEFORMAT_2;Unsigned 16 bits +!SAMPLEFORMAT_4;LogLuv 24 bits +!SAMPLEFORMAT_8;LogLuv 32 bits +!SAMPLEFORMAT_16;32 bits floating point !SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists !SAVEDLG_FILEFORMAT;File format !SAVEDLG_FORCEFORMATOPTS;Force saving options !SAVEDLG_JPEGQUAL;JPEG quality -!SAVEDLG_PNGCOMPR;PNG compression !SAVEDLG_PUTTOQUEUE;Put into processing queue !SAVEDLG_PUTTOQUEUEHEAD;Put to the head of the processing queue !SAVEDLG_PUTTOQUEUETAIL;Put to the end of the processing queue @@ -1251,7 +1273,6 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !SAVEDLG_TIFFUNCOMPRESSED;Uncompressed TIFF !SAVEDLG_WARNFILENAME;File will be named !SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. -!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate de rendering generated by the output profile of the ICM tool. Most useful for simulating printing outputs. !THRESHOLDSELECTOR_B;Bottom !THRESHOLDSELECTOR_BL;Bottom-left !THRESHOLDSELECTOR_BR;Bottom-right @@ -1393,7 +1414,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !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 Tint=1.\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\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504 !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_WBCAM;WB [RT+CAT02] + [output] @@ -1665,7 +1686,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !TP_LENSGEOM_AUTOCROP;Auto-Crop !TP_LENSGEOM_FILL;Auto-fill !TP_LENSGEOM_LABEL;Lens / Geometry -!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_LABEL;Profiled Lens Correction !TP_LENSPROFILE_USECA;Chromatic aberration correction !TP_LENSPROFILE_USEDIST;Distortion correction !TP_LENSPROFILE_USEVIGN;Vignetting correction @@ -1917,6 +1938,9 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !TP_SHARPENMICRO_LABEL;Microcontrast !TP_SHARPENMICRO_MATRIX;3×3 matrix instead of 5×5 !TP_SHARPENMICRO_UNIFORMITY;Uniformity +!TP_TM_FATTAL_AMOUNT;Amount +!TP_TM_FATTAL_LABEL;HDR Tone Mapping +!TP_TM_FATTAL_THRESHOLD;Threshold !TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH !TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones !TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Red/Purple diff --git a/rtdata/languages/English (US) b/rtdata/languages/English (US) index 801f34603..31093bc2b 100644 --- a/rtdata/languages/English (US) +++ b/rtdata/languages/English (US) @@ -72,6 +72,7 @@ !EXIFPANEL_RESETALL;Reset All !EXIFPANEL_RESETALLHINT;Reset all tags to their original values. !EXIFPANEL_RESETHINT;Reset the selected tags to their original values. +!EXIFPANEL_SHOWALL;Show all !EXIFPANEL_SUBDIRECTORY;Subdirectory !EXPORT_BYPASS;Processing steps to bypass !EXPORT_BYPASS_ALL;Select / Unselect All @@ -282,9 +283,9 @@ !HISTORY_MSG_31;RLD - Amount !HISTORY_MSG_32;RLD - Damping !HISTORY_MSG_33;RLD - Iterations -!HISTORY_MSG_34;LCP distortion correction -!HISTORY_MSG_35;LCP vignetting correction -!HISTORY_MSG_36;LCP CA correction +!HISTORY_MSG_34;Lens Correction - Distortion +!HISTORY_MSG_35;Lens Correction - Vignetting +!HISTORY_MSG_36;Lens Correction - CA !HISTORY_MSG_37;Exposure - Auto levels !HISTORY_MSG_38;White Balance - Method !HISTORY_MSG_39;WB - Temperature @@ -333,7 +334,7 @@ !HISTORY_MSG_82;Profile changed !HISTORY_MSG_83;S/H - Sharp mask !HISTORY_MSG_84;Perspective correction -!HISTORY_MSG_85;LCP +!HISTORY_MSG_85;Lens Correction - LCP file !HISTORY_MSG_86;RGB Curves - Luminosity mode !HISTORY_MSG_87;Impulse Noise Reduction !HISTORY_MSG_88;Impulse NR threshold @@ -716,6 +717,12 @@ !HISTORY_MSG_482;CAM02 - Green scene !HISTORY_MSG_483;CAM02 - Yb scene !HISTORY_MSG_484;CAM02 - Auto Yb scene +!HISTORY_MSG_485;Lens Correction +!HISTORY_MSG_486;Lens Correction - Camera +!HISTORY_MSG_487;Lens Correction - Lens +!HISTORY_MSG_488;HDR Tone Mapping +!HISTORY_MSG_489;HDR TM - Threshold +!HISTORY_MSG_490;HDR TM - Amount !HISTORY_NEWSNAPSHOT;Add !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !HISTORY_SNAPSHOT;Snapshot @@ -762,6 +769,10 @@ !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. +!LENSPROFILE_CORRECTION_AUTOMATCH;Auto-matched correction parameters +!LENSPROFILE_CORRECTION_LCPFILE;LCP File +!LENSPROFILE_CORRECTION_MANUAL;Manual correction parameters +!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. !MAIN_BUTTON_FULLSCREEN;Fullscreen !MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the next image relative to image opened in the Editor.\nShortcut: Shift-F4\n\nTo navigate to the next image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F4 !MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the previous image relative to image opened in the Editor.\nShortcut: Shift-F3\n\nTo navigate to the previous image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F3 @@ -820,6 +831,7 @@ !MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 9 !MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 !MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 9 +!MAIN_TOOLTIP_BACKCOLOR3;Background color of the preview: Middle grey\nShortcut: 9 !MAIN_TOOLTIP_BEFOREAFTERLOCK;Lock / Unlock the Before view\n\nLock: keep the Before view unchanged.\nUseful to evaluate the cumulative effect of multiple tools.\nAdditionally, comparisons can be made to any state in the History.\n\nUnlock: the Before view will follow the After view one step behind, showing the image before the effect of the currently used tool. !MAIN_TOOLTIP_HIDEHP;Show/Hide the left panel (including the history).\nShortcut: l !MAIN_TOOLTIP_INDCLIPPEDH;Clipped highlight indication.\nShortcut: < @@ -887,7 +899,7 @@ !PARTIALPASTE_IPTCINFO;IPTC !PARTIALPASTE_LABCURVE;L*a*b* adjustments !PARTIALPASTE_LENSGROUP;Lens Related Settings -!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_LENSPROFILE;Profiled lens correction !PARTIALPASTE_METAGROUP;Metadata !PARTIALPASTE_PCVIGNETTE;Vignette filter !PARTIALPASTE_PERSPECTIVE;Perspective @@ -908,7 +920,7 @@ !PARTIALPASTE_RAW_FALSECOLOR;False color suppression !PARTIALPASTE_RAW_IMAGENUM;Sub-image !PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps -!PARTIALPASTE_RAW_PIXELSHIFT;PixelShift +!PARTIALPASTE_RAW_PIXELSHIFT;Pixel Shift !PARTIALPASTE_RESIZE;Resize !PARTIALPASTE_RETINEX;Retinex !PARTIALPASTE_RGBCURVES;RGB curves @@ -917,6 +929,7 @@ !PARTIALPASTE_SHARPENEDGE;Edges !PARTIALPASTE_SHARPENING;Sharpening (USM/RL) !PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_TM_FATTAL;HDR Tone mapping !PARTIALPASTE_VIBRANCE;Vibrance !PARTIALPASTE_VIGNETTING;Vignetting correction !PARTIALPASTE_WAVELETGROUP;Wavelet Levels @@ -929,6 +942,7 @@ !PREFERENCES_AUTLISVLOW;None !PREFERENCES_AUTLOW;Low !PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +!PREFERENCES_AUTOSAVE_TP_OPEN;Automatically save tools collapsed/expanded\nstate before exiting !PREFERENCES_AUTSTD;Standard !PREFERENCES_BATCH_PROCESSING;Batch Processing !PREFERENCES_BEHADDALL;All to 'Add' @@ -969,7 +983,6 @@ !PREFERENCES_D55;5500K !PREFERENCES_D60;6000K !PREFERENCES_D65;6500K -!PREFERENCES_DARKFRAME;Dark-Frame !PREFERENCES_DARKFRAMEFOUND;Found !PREFERENCES_DARKFRAMESHOTS;shots !PREFERENCES_DARKFRAMETEMPLATES;templates @@ -978,6 +991,7 @@ !PREFERENCES_DAUB_LABEL;Use Daubechies D6 wavelets instead of D4 !PREFERENCES_DAUB_TOOLTIP;The Noise Reduction and Wavelet Levels tools use a Debauchies mother wavelet. If you choose D6 instead of D4 you increase the number of orthogonal Daubechies coefficients and probably increase quality of small-scale levels. There is no memory or processing time difference between the two. !PREFERENCES_DIRDARKFRAMES;Dark-frames directory +!PREFERENCES_DIRECTORIES;Directories !PREFERENCES_DIRHOME;Home directory !PREFERENCES_DIRLAST;Last visited directory !PREFERENCES_DIROTHER;Other @@ -990,8 +1004,6 @@ !PREFERENCES_FBROWSEROPTS;File Browser / Thumbnail Options !PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar\n(de-select for low resolution display) !PREFERENCES_FILEFORMAT;File format -!PREFERENCES_FILMSIMULATION;Film Simulation -!PREFERENCES_FLATFIELD;Flat-Field !PREFERENCES_FLATFIELDFOUND;Found !PREFERENCES_FLATFIELDSDIR;Flat-fields directory !PREFERENCES_FLATFIELDSHOTS;shots @@ -1093,6 +1105,7 @@ !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_RGBDTL_LABEL;Max number of threads for Noise Reduction and Wavelet Levels !PREFERENCES_RGBDTL_TOOLTIP;Leave the setting at "0" to automatically use as many threads as possible. The more threads run in parallel, the faster the computation. Refer to RawPedia for memory requirements. +!PREFERENCES_SAVE_TP_OPEN_NOW;Save tools collapsed/expanded state now !PREFERENCES_SELECTFONT;Select main font !PREFERENCES_SELECTFONT_COLPICKER;Select Color Picker's font !PREFERENCES_SELECTLANG;Select language @@ -1171,13 +1184,21 @@ !PROGRESSBAR_SAVETIFF;Saving TIFF file... !PROGRESSBAR_SNAPSHOT_ADDED;Snapshot added !PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!QINFO_FRAMECOUNT;%2 frames +!QINFO_HDR;HDR / %2 frame(s) !QINFO_ISO;ISO !QINFO_NOEXIF;Exif data not available. +!QINFO_PIXELSHIFT;Pixel Shift / %2 frame(s) +!SAMPLEFORMAT_0;Unknown data format +!SAMPLEFORMAT_1;Unsigned 8 bits +!SAMPLEFORMAT_2;Unsigned 16 bits +!SAMPLEFORMAT_4;LogLuv 24 bits +!SAMPLEFORMAT_8;LogLuv 32 bits +!SAMPLEFORMAT_16;32 bits floating point !SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists !SAVEDLG_FILEFORMAT;File format !SAVEDLG_FORCEFORMATOPTS;Force saving options !SAVEDLG_JPEGQUAL;JPEG quality -!SAVEDLG_PNGCOMPR;PNG compression !SAVEDLG_PUTTOQUEUE;Put into processing queue !SAVEDLG_PUTTOQUEUEHEAD;Put to the head of the processing queue !SAVEDLG_PUTTOQUEUETAIL;Put to the end of the processing queue @@ -1191,8 +1212,8 @@ !SAVEDLG_TIFFUNCOMPRESSED;Uncompressed TIFF !SAVEDLG_WARNFILENAME;File will be named !SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. -!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the output profile. -!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate de rendering generated by the output profile of the ICM tool. Most useful for simulating printing outputs. +!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the Printer profile. +!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate the printer's output by using the Printer profile set in Preferences > Color Management. !THRESHOLDSELECTOR_B;Bottom !THRESHOLDSELECTOR_BL;Bottom-left !THRESHOLDSELECTOR_BR;Bottom-right @@ -1352,7 +1373,7 @@ !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 Tint=1.\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\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504 !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_WBCAM;WB [RT+CAT02] + [output] @@ -1652,7 +1673,7 @@ !TP_LENSGEOM_AUTOCROP;Auto-Crop !TP_LENSGEOM_FILL;Auto-fill !TP_LENSGEOM_LABEL;Lens / Geometry -!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_LABEL;Profiled Lens Correction !TP_LENSPROFILE_USECA;Chromatic aberration correction !TP_LENSPROFILE_USEDIST;Distortion correction !TP_LENSPROFILE_USEVIGN;Vignetting correction @@ -1908,6 +1929,9 @@ !TP_SHARPENMICRO_LABEL;Microcontrast !TP_SHARPENMICRO_MATRIX;3×3 matrix instead of 5×5 !TP_SHARPENMICRO_UNIFORMITY;Uniformity +!TP_TM_FATTAL_AMOUNT;Amount +!TP_TM_FATTAL_LABEL;HDR Tone Mapping +!TP_TM_FATTAL_THRESHOLD;Threshold !TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift !TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH !TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones diff --git a/rtdata/languages/Espanol b/rtdata/languages/Espanol index 7fd2b54ab..ec6dcfb37 100644 --- a/rtdata/languages/Espanol +++ b/rtdata/languages/Espanol @@ -759,7 +759,6 @@ PREFERENCES_D50;5000ºK PREFERENCES_D55;5500ºK PREFERENCES_D60;6000ºK PREFERENCES_D65;6500ºK -PREFERENCES_DARKFRAME;Toma Negra PREFERENCES_DARKFRAMEFOUND;Encontrado PREFERENCES_DARKFRAMESHOTS;disparos PREFERENCES_DARKFRAMETEMPLATES;plantillas @@ -777,8 +776,6 @@ PREFERENCES_EXTERNALEDITOR;Editor externo PREFERENCES_FBROWSEROPTS;Opciones del explorador de archivos/Miniaturas PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Barra de herramientas del explorador en una sola fila (deseleccionar para pantallas de baja resolución) PREFERENCES_FILEFORMAT;Formato de archivo -PREFERENCES_FILMSIMULATION;Simulación de Fílmico -PREFERENCES_FLATFIELD;Campo plano PREFERENCES_FLATFIELDFOUND;Encontrado PREFERENCES_FLATFIELDSDIR;Carpeta de archivos de campo plano PREFERENCES_FLATFIELDSHOTS;disparos @@ -1515,6 +1512,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nAtajo: - !DYNPROFILEEDITOR_NEW;New !DYNPROFILEEDITOR_NEW_RULE;New Dynamic Profile Rule !DYNPROFILEEDITOR_PROFILE;Processing Profile +!EXIFPANEL_SHOWALL;Show all !EXPORT_BYPASS;Processing steps to bypass !EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels !EXPORT_PIPELINE;Processing pipeline @@ -1707,6 +1705,12 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nAtajo: - !HISTORY_MSG_482;CAM02 - Green scene !HISTORY_MSG_483;CAM02 - Yb scene !HISTORY_MSG_484;CAM02 - Auto Yb scene +!HISTORY_MSG_485;Lens Correction +!HISTORY_MSG_486;Lens Correction - Camera +!HISTORY_MSG_487;Lens Correction - Lens +!HISTORY_MSG_488;HDR Tone Mapping +!HISTORY_MSG_489;HDR TM - Threshold +!HISTORY_MSG_490;HDR TM - Amount !IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider. !IPTCPANEL_CITYHINT;Enter the name of the city pictured in this image. !IPTCPANEL_COPYRIGHT;Copyright notice @@ -1732,10 +1736,15 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nAtajo: - !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. +!LENSPROFILE_CORRECTION_AUTOMATCH;Auto-matched correction parameters +!LENSPROFILE_CORRECTION_LCPFILE;LCP File +!LENSPROFILE_CORRECTION_MANUAL;Manual correction parameters +!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. !MAIN_MSG_TOOMANYOPENEDITORS;Too many open editors.\nPlease close an editor to continue. !MAIN_TAB_INSPECT; Inspect !MAIN_TAB_WAVELET;Wavelet !MAIN_TAB_WAVELET_TOOLTIP;Shortcut: Alt-w +!MAIN_TOOLTIP_BACKCOLOR3;Background color of the preview: Middle grey\nShortcut: 9 !MONITOR_PROFILE_SYSTEM;System default !NAVIGATOR_B;B: !NAVIGATOR_G;G: @@ -1751,14 +1760,16 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nAtajo: - !PARTIALPASTE_PRSHARPENING;Post-resize sharpening !PARTIALPASTE_RAWCACORR_CAREDBLUE;CA red & blue !PARTIALPASTE_RAW_IMAGENUM;Sub-image -!PARTIALPASTE_RAW_PIXELSHIFT;PixelShift +!PARTIALPASTE_RAW_PIXELSHIFT;Pixel Shift !PARTIALPASTE_RETINEX;Retinex +!PARTIALPASTE_TM_FATTAL;HDR Tone mapping !PARTIALPASTE_WAVELETGROUP;Wavelet Levels !PREFERENCES_AUTLISLOW;Low !PREFERENCES_AUTLISMAX;Max - Average of all tiles !PREFERENCES_AUTLISSTD;High !PREFERENCES_AUTLISVLOW;None !PREFERENCES_AUTLOW;Low +!PREFERENCES_AUTOSAVE_TP_OPEN;Automatically save tools collapsed/expanded\nstate before exiting !PREFERENCES_AUTSTD;Standard !PREFERENCES_CIEART_FRAME;CIECAM02-Specific Settings !PREFERENCES_CLUTSCACHE;HaldCLUT Cache @@ -1772,6 +1783,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nAtajo: - !PREFERENCES_D50_OLD;5000K !PREFERENCES_DAUB_LABEL;Use Daubechies D6 wavelets instead of D4 !PREFERENCES_DAUB_TOOLTIP;The Noise Reduction and Wavelet Levels tools use a Debauchies mother wavelet. If you choose D6 instead of D4 you increase the number of orthogonal Daubechies coefficients and probably increase quality of small-scale levels. There is no memory or processing time difference between the two. +!PREFERENCES_DIRECTORIES;Directories !PREFERENCES_EXPAUT;Expert !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. @@ -1812,6 +1824,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nAtajo: - !PREFERENCES_PRTPROFILE;Color profile !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 tools collapsed/expanded state now !PREFERENCES_SELECTFONT_COLPICKER;Select Color Picker's font !PREFERENCES_SERIALIZE_TIFF_READ;Tiff Read Settings !PREFERENCES_SERIALIZE_TIFF_READ_LABEL;Serialize read of tiff files @@ -1831,9 +1844,18 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nAtajo: - !PREFERENCES_WLTWO;Two levels !PREFERENCES_WLZER;No !PROFILEPANEL_PDYNAMIC;Dynamic +!QINFO_FRAMECOUNT;%2 frames +!QINFO_HDR;HDR / %2 frame(s) +!QINFO_PIXELSHIFT;Pixel Shift / %2 frame(s) +!SAMPLEFORMAT_0;Unknown data format +!SAMPLEFORMAT_1;Unsigned 8 bits +!SAMPLEFORMAT_2;Unsigned 16 bits +!SAMPLEFORMAT_4;LogLuv 24 bits +!SAMPLEFORMAT_8;LogLuv 32 bits +!SAMPLEFORMAT_16;32 bits 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;If active, indicates in grey the pixels which have out of gamut colors from the output profile. -!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate de rendering generated by the output profile of the ICM tool. Most useful for simulating printing outputs. +!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the Printer profile. +!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate the printer's output by using the Printer profile set in Preferences > Color Management. !TOOLBAR_TOOLTIP_COLORPICKER;Lockable Color Picker\n\nWhen enabled:\nClick in the preview with left mouse button to add a color picker\nDrag it around while pressing the left mouse button\nDelete the color picker with a right mouse button click\nDelete all color pickers with Shift + Right mouse button click\nRight click away from any color picker to go back to the Hand tool !TP_CBDL_AFT;After Black-and-White !TP_CBDL_BEF;Before Black-and-White @@ -1842,7 +1864,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nAtajo: - !TP_COLORAPP_FREE;Free temp+green + CAT02 + [output] !TP_COLORAPP_NEUTRAL;Reset !TP_COLORAPP_NEUTRAL_TIP;Reset all sliders checkbox and curves to their default values -!TP_COLORAPP_TEMP_TOOLTIP;To select an illuminant always Tint=1.\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\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504 !TP_COLORAPP_YB;Yb% (mean luminance) !TP_COLORAPP_YBSCENE;Yb% (mean luminance) !TP_COLORAPP_YBSCENE_TOOLTIP;if auto enable, Yb is calculated from the mean value of actual image luminance @@ -2049,6 +2071,9 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nAtajo: - !TP_RETINEX_VIEW_TRAN;Transmission - Auto !TP_RETINEX_VIEW_TRAN2;Transmission - Fixed !TP_RETINEX_VIEW_UNSHARP;Unsharp mask +!TP_TM_FATTAL_AMOUNT;Amount +!TP_TM_FATTAL_LABEL;HDR Tone Mapping +!TP_TM_FATTAL_THRESHOLD;Threshold !TP_WAVELET_1;Level 1 !TP_WAVELET_2;Level 2 !TP_WAVELET_3;Level 3 diff --git a/rtdata/languages/Euskara b/rtdata/languages/Euskara index 94c651b08..8718554f5 100644 --- a/rtdata/languages/Euskara +++ b/rtdata/languages/Euskara @@ -463,6 +463,7 @@ TP_WBALANCE_TEMPERATURE;Tenperatura !EXIFFILTER_EXPOSURECOMPENSATION;Exposure compensation (EV) !EXIFFILTER_FILETYPE;File type !EXIFFILTER_METADATAFILTER;Enable metadata filters +!EXIFPANEL_SHOWALL;Show all !EXPORT_BYPASS;Processing steps to bypass !EXPORT_BYPASS_ALL;Select / Unselect All !EXPORT_BYPASS_DEFRINGE;Bypass Defringe @@ -585,7 +586,7 @@ TP_WBALANCE_TEMPERATURE;Tenperatura !HISTORY_MSG_82;Profile changed !HISTORY_MSG_83;S/H - Sharp mask !HISTORY_MSG_84;Perspective correction -!HISTORY_MSG_85;LCP +!HISTORY_MSG_85;Lens Correction - LCP file !HISTORY_MSG_86;RGB Curves - Luminosity mode !HISTORY_MSG_87;Impulse Noise Reduction !HISTORY_MSG_88;Impulse NR threshold @@ -968,6 +969,12 @@ TP_WBALANCE_TEMPERATURE;Tenperatura !HISTORY_MSG_482;CAM02 - Green scene !HISTORY_MSG_483;CAM02 - Yb scene !HISTORY_MSG_484;CAM02 - Auto Yb scene +!HISTORY_MSG_485;Lens Correction +!HISTORY_MSG_486;Lens Correction - Camera +!HISTORY_MSG_487;Lens Correction - Lens +!HISTORY_MSG_488;HDR Tone Mapping +!HISTORY_MSG_489;HDR TM - Threshold +!HISTORY_MSG_490;HDR TM - Amount !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider. !IPTCPANEL_CITYHINT;Enter the name of the city pictured in this image. @@ -994,6 +1001,10 @@ TP_WBALANCE_TEMPERATURE;Tenperatura !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. +!LENSPROFILE_CORRECTION_AUTOMATCH;Auto-matched correction parameters +!LENSPROFILE_CORRECTION_LCPFILE;LCP File +!LENSPROFILE_CORRECTION_MANUAL;Manual correction parameters +!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. !MAIN_BUTTON_FULLSCREEN;Fullscreen !MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the next image relative to image opened in the Editor.\nShortcut: Shift-F4\n\nTo navigate to the next image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F4 !MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the previous image relative to image opened in the Editor.\nShortcut: Shift-F3\n\nTo navigate to the previous image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F3 @@ -1029,6 +1040,7 @@ TP_WBALANCE_TEMPERATURE;Tenperatura !MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 9 !MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 !MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 9 +!MAIN_TOOLTIP_BACKCOLOR3;Background color of the preview: Middle grey\nShortcut: 9 !MAIN_TOOLTIP_BEFOREAFTERLOCK;Lock / Unlock the Before view\n\nLock: keep the Before view unchanged.\nUseful to evaluate the cumulative effect of multiple tools.\nAdditionally, comparisons can be made to any state in the History.\n\nUnlock: the Before view will follow the After view one step behind, showing the image before the effect of the currently used tool. !MAIN_TOOLTIP_PREVIEWB;Preview the Blue channel.\nShortcut: b !MAIN_TOOLTIP_PREVIEWFOCUSMASK;Preview the Focus Mask.\nShortcut: Shift-f\n\nMore accurate on images with shallow depth of field, low noise and at higher zoom levels.\n\nTo improve detection accuracy for noisy images evaluate at smaller zoom, about 10-30%. @@ -1079,7 +1091,7 @@ TP_WBALANCE_TEMPERATURE;Tenperatura !PARTIALPASTE_HSVEQUALIZER;HSV equalizer !PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction !PARTIALPASTE_LABCURVE;L*a*b* adjustments -!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_LENSPROFILE;Profiled lens correction !PARTIALPASTE_PCVIGNETTE;Vignette filter !PARTIALPASTE_PERSPECTIVE;Perspective !PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter @@ -1099,11 +1111,12 @@ TP_WBALANCE_TEMPERATURE;Tenperatura !PARTIALPASTE_RAW_FALSECOLOR;False color suppression !PARTIALPASTE_RAW_IMAGENUM;Sub-image !PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps -!PARTIALPASTE_RAW_PIXELSHIFT;PixelShift +!PARTIALPASTE_RAW_PIXELSHIFT;Pixel Shift !PARTIALPASTE_RETINEX;Retinex !PARTIALPASTE_RGBCURVES;RGB curves !PARTIALPASTE_SHARPENEDGE;Edges !PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_TM_FATTAL;HDR Tone mapping !PARTIALPASTE_VIBRANCE;Vibrance !PARTIALPASTE_WAVELETGROUP;Wavelet Levels !PREFERENCES_ADD;Add @@ -1113,6 +1126,7 @@ TP_WBALANCE_TEMPERATURE;Tenperatura !PREFERENCES_AUTLISVLOW;None !PREFERENCES_AUTLOW;Low !PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +!PREFERENCES_AUTOSAVE_TP_OPEN;Automatically save tools collapsed/expanded\nstate before exiting !PREFERENCES_AUTSTD;Standard !PREFERENCES_BATCH_PROCESSING;Batch Processing !PREFERENCES_BEHADDALL;All to 'Add' @@ -1146,18 +1160,16 @@ TP_WBALANCE_TEMPERATURE;Tenperatura !PREFERENCES_D55;5500K !PREFERENCES_D60;6000K !PREFERENCES_D65;6500K -!PREFERENCES_DARKFRAME;Dark-Frame !PREFERENCES_DARKFRAMEFOUND;Found !PREFERENCES_DARKFRAMESHOTS;shots !PREFERENCES_DARKFRAMETEMPLATES;templates !PREFERENCES_DAUB_LABEL;Use Daubechies D6 wavelets instead of D4 !PREFERENCES_DAUB_TOOLTIP;The Noise Reduction and Wavelet Levels tools use a Debauchies mother wavelet. If you choose D6 instead of D4 you increase the number of orthogonal Daubechies coefficients and probably increase quality of small-scale levels. There is no memory or processing time difference between the two. !PREFERENCES_DIRDARKFRAMES;Dark-frames directory +!PREFERENCES_DIRECTORIES;Directories !PREFERENCES_EDITORLAYOUT;Editor Layout !PREFERENCES_EXPAUT;Expert !PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar\n(de-select for low resolution display) -!PREFERENCES_FILMSIMULATION;Film Simulation -!PREFERENCES_FLATFIELD;Flat-Field !PREFERENCES_FLATFIELDFOUND;Found !PREFERENCES_FLATFIELDSDIR;Flat-fields directory !PREFERENCES_FLATFIELDSHOTS;shots @@ -1233,6 +1245,7 @@ TP_WBALANCE_TEMPERATURE;Tenperatura !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_RGBDTL_LABEL;Max number of threads for Noise Reduction and Wavelet Levels !PREFERENCES_RGBDTL_TOOLTIP;Leave the setting at "0" to automatically use as many threads as possible. The more threads run in parallel, the faster the computation. Refer to RawPedia for memory requirements. +!PREFERENCES_SAVE_TP_OPEN_NOW;Save tools collapsed/expanded state now !PREFERENCES_SELECTFONT;Select main font !PREFERENCES_SELECTFONT_COLPICKER;Select Color Picker's font !PREFERENCES_SERIALIZE_TIFF_READ;Tiff Read Settings @@ -1282,6 +1295,15 @@ TP_WBALANCE_TEMPERATURE;Tenperatura !PROGRESSBAR_PROCESSING_PROFILESAVED;Processing profile saved !PROGRESSBAR_SNAPSHOT_ADDED;Snapshot added !PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!QINFO_FRAMECOUNT;%2 frames +!QINFO_HDR;HDR / %2 frame(s) +!QINFO_PIXELSHIFT;Pixel Shift / %2 frame(s) +!SAMPLEFORMAT_0;Unknown data format +!SAMPLEFORMAT_1;Unsigned 8 bits +!SAMPLEFORMAT_2;Unsigned 16 bits +!SAMPLEFORMAT_4;LogLuv 24 bits +!SAMPLEFORMAT_8;LogLuv 32 bits +!SAMPLEFORMAT_16;32 bits floating point !SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists !SAVEDLG_FORCEFORMATOPTS;Force saving options !SAVEDLG_SUBSAMP;Subsampling @@ -1292,8 +1314,8 @@ TP_WBALANCE_TEMPERATURE;Tenperatura !SAVEDLG_TIFFUNCOMPRESSED;Uncompressed TIFF !SAVEDLG_WARNFILENAME;File will be named !SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. -!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the output profile. -!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate de rendering generated by the output profile of the ICM tool. Most useful for simulating printing outputs. +!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the Printer profile. +!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate the printer's output by using the Printer profile set in Preferences > Color Management. !THRESHOLDSELECTOR_B;Bottom !THRESHOLDSELECTOR_BL;Bottom-left !THRESHOLDSELECTOR_BR;Bottom-right @@ -1438,7 +1460,7 @@ TP_WBALANCE_TEMPERATURE;Tenperatura !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 Tint=1.\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\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504 !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_WBCAM;WB [RT+CAT02] + [output] @@ -1702,7 +1724,7 @@ TP_WBALANCE_TEMPERATURE;Tenperatura !TP_LENSGEOM_AUTOCROP;Auto-Crop !TP_LENSGEOM_FILL;Auto-fill !TP_LENSGEOM_LABEL;Lens / Geometry -!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_LABEL;Profiled Lens Correction !TP_LENSPROFILE_USECA;Chromatic aberration correction !TP_LENSPROFILE_USEDIST;Distortion correction !TP_LENSPROFILE_USEVIGN;Vignetting correction @@ -1925,6 +1947,9 @@ TP_WBALANCE_TEMPERATURE;Tenperatura !TP_SHARPENMICRO_LABEL;Microcontrast !TP_SHARPENMICRO_MATRIX;3×3 matrix instead of 5×5 !TP_SHARPENMICRO_UNIFORMITY;Uniformity +!TP_TM_FATTAL_AMOUNT;Amount +!TP_TM_FATTAL_LABEL;HDR Tone Mapping +!TP_TM_FATTAL_THRESHOLD;Threshold !TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift !TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH !TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones diff --git a/rtdata/languages/Francais b/rtdata/languages/Francais index 088e8d5f1..649f9c5d8 100644 --- a/rtdata/languages/Francais +++ b/rtdata/languages/Francais @@ -68,6 +68,7 @@ EXIFPANEL_RESET;Réinitialiser EXIFPANEL_RESETALL;Réinitialiser tout EXIFPANEL_RESETALLHINT;Réinitialise tous les tags à leur valeur initiale EXIFPANEL_RESETHINT;Réinitialise les données sélectionnées à la valeur initiale +EXIFPANEL_SHOWALL;Voir tout EXIFPANEL_SUBDIRECTORY;Sous-répertoire EXPORT_BYPASS;Étapes de traitement à ignorer EXPORT_BYPASS_ALL;Sélectionner / Désélectionner tout @@ -702,6 +703,9 @@ HISTORY_MSG_472;PS - Adoucir les transitions HISTORY_MSG_473;PS - Utiliser LMMSE HISTORY_MSG_474;PS - Égaliser HISTORY_MSG_475;PS - Égaliser par canal +HISTORY_MSG_488;Compression tonale HDR +HISTORY_MSG_489;CT HDR - Seuil +HISTORY_MSG_490;CT HDR - Quantité HISTORY_NEWSNAPSHOT;Ajouter HISTORY_NEWSNAPSHOT_TOOLTIP;Raccourci: Alt-s HISTORY_SNAPSHOT;Capture @@ -903,6 +907,7 @@ PARTIALPASTE_SHADOWSHIGHLIGHTS;Ombres/Hautes lumières PARTIALPASTE_SHARPENEDGE;Bords PARTIALPASTE_SHARPENING;Netteté PARTIALPASTE_SHARPENMICRO;Microcontraste +PARTIALPASTE_TM_FATTAL;Compression tonale HDR (Fattal02) PARTIALPASTE_VIBRANCE;Vibrance PARTIALPASTE_VIGNETTING;Correction du vignettage PARTIALPASTE_WAVELETGROUP;Niveaux d'ondelette @@ -954,7 +959,6 @@ PREFERENCES_D50;5000K PREFERENCES_D55;5500K PREFERENCES_D60;6000K PREFERENCES_D65;6500K -PREFERENCES_DARKFRAME;Soustraction de Trame Noire PREFERENCES_DARKFRAMEFOUND;Trouvé PREFERENCES_DARKFRAMESHOTS;image(s) PREFERENCES_DARKFRAMETEMPLATES;modèle(s) @@ -963,6 +967,7 @@ PREFERENCES_DATEFORMATHINT;Vous pouvez utiliser les paramètres de chaînes f PREFERENCES_DAUB_LABEL;Utiliser les ondelettes de Daubechies D6 au lieu de D4 PREFERENCES_DAUB_TOOLTIP;Les outils de Réduction de Bruit et de Niveaux d'Ondelettes utilisent une ondelette de Debauchie mère. Si vous choisissez D6 au lieu de D4 vous augmentez le nombre de coéf. orthogonaux de Daubechies et augmentez probablement la qualité des niveaux de taille moyenne. Il n'y a pas de différence de consommation mémoire ou de temps de traitement entre les deux. PREFERENCES_DIRDARKFRAMES;Dossier des images de Trame Noire +PREFERENCES_DIRECTORIES;Dossiers PREFERENCES_DIRHOME;Racine de mes documents personnels PREFERENCES_DIRLAST;Dernier dossier visité PREFERENCES_DIROTHER;Autre @@ -975,8 +980,6 @@ PREFERENCES_EXTERNALEDITOR;Éditeur externe PREFERENCES_FBROWSEROPTS;Options du navigateur de fichiers et de vignettes PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Barre de menu de l'explorateur de fichiers uni-ligne\n(à désactiver pour les écrans de faible résolution) PREFERENCES_FILEFORMAT;Format du fichier -PREFERENCES_FILMSIMULATION;Simulation de Film -PREFERENCES_FLATFIELD;Champ Uniforme PREFERENCES_FLATFIELDFOUND;Trouvé PREFERENCES_FLATFIELDSDIR;Dossier des images de Champ Uniforme PREFERENCES_FLATFIELDSHOTS;image(s) @@ -1153,8 +1156,17 @@ PROGRESSBAR_SAVEPNG;Enregistrement du fichier PNG... PROGRESSBAR_SAVETIFF;Enregistrement du fichier TIFF... PROGRESSBAR_SNAPSHOT_ADDED;Signet ajouté PROGRESSDLG_PROFILECHANGEDINBROWSER;Profil modifié dans le navigateur +QINFO_FRAMECOUNT;%2 images +QINFO_HDR;HDR / %2 image(s) QINFO_ISO;ISO QINFO_NOEXIF;Données EXIF non disponibles. +QINFO_PIXELSHIFT;PixelShift / %2 images +SAMPLEFORMAT_0;Format de donnée inconnu +SAMPLEFORMAT_1;8 bits non signé +SAMPLEFORMAT_2;16 bits non signé +SAMPLEFORMAT_4;LogLuv 24 bits +SAMPLEFORMAT_8;LogLuv 32 bits +SAMPLEFORMAT_16;32 bits à virgule flottante SAVEDLG_AUTOSUFFIX;Ajouter automatiquement un suffixe si le fichier existe déjà SAVEDLG_FILEFORMAT;Format de fichier SAVEDLG_FORCEFORMATOPTS;Forcer les options d'enregistrement @@ -1173,8 +1185,8 @@ SAVEDLG_SUBSAMP_TOOLTIP;Meilleurs compression:\nJ:a:b 4:2:0\nh/v 2/2\nChroma div SAVEDLG_TIFFUNCOMPRESSED;TIFF non compressé SAVEDLG_WARNFILENAME;Le fichier sera nommé SHCSELECTOR_TOOLTIP;Cliquez le bouton droit de la souris\npour réinitialiser la position de ces 3 curseurs -SOFTPROOF_GAMUTCHECK_TOOLTIP;Si activé, indique en gris les pixels dont la couleurs est en dehors du gamut du profil de sortie -SOFTPROOF_TOOLTIP;Épreuvage écran\nSi activé, simule le rendu généré par le profile de sortie de l'outil ICM. Particulièrement utile pour simuler le rendu en sortie d'imprimante. +SOFTPROOF_GAMUTCHECK_TOOLTIP;Si activé, indique en gris les pixels dont la couleurs est en dehors du gamut du profil Imprimante +SOFTPROOF_TOOLTIP;Épreuvage écran\nSi activé, vous permet de simuler le rendu obtenu par votre imprimante en utilisant le profil Imprimante réglé dans Préférences > Gestion des couleurs. THRESHOLDSELECTOR_B;Bas THRESHOLDSELECTOR_BL;Bas-gauche THRESHOLDSELECTOR_BR;Bas-droite @@ -1887,6 +1899,9 @@ TP_SHARPENMICRO_UNIFORMITY;Uniformité TP_SPOT_COUNTLABEL;%1 point(s) TP_SPOT_ENTRYCHANGED;Modification d'un point TP_SPOT_LABEL;Retrait de taches +TP_TM_FATTAL_AMOUNT;Quantité +TP_TM_FATTAL_LABEL;Compression Tonale HDR (Fattal02) +TP_TM_FATTAL_THRESHOLD;Seuil TP_VIBRANCE_AVOIDCOLORSHIFT;Éviter les dérives de teinte TP_VIBRANCE_CURVEEDITOR_SKINTONES;TT TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Tons chair @@ -2145,14 +2160,24 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !HISTORY_MSG_482;CAM02 - Green scene !HISTORY_MSG_483;CAM02 - Yb scene !HISTORY_MSG_484;CAM02 - Auto Yb scene +!HISTORY_MSG_485;Lens Correction +!HISTORY_MSG_486;Lens Correction - Camera +!HISTORY_MSG_487;Lens Correction - Lens +!LENSPROFILE_CORRECTION_AUTOMATCH;Auto-matched correction parameters +!LENSPROFILE_CORRECTION_LCPFILE;LCP File +!LENSPROFILE_CORRECTION_MANUAL;Manual correction parameters +!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. +!MAIN_TOOLTIP_BACKCOLOR3;Background color of the preview: Middle grey\nShortcut: 9 +!PREFERENCES_AUTOSAVE_TP_OPEN;Automatically save tools collapsed/expanded\nstate before exiting !PREFERENCES_D50_OLD;5000K !PREFERENCES_GREY18_OLD;Yb=18 CIE L#50 !PREFERENCES_LANG;Language +!PREFERENCES_SAVE_TP_OPEN_NOW;Save tools collapsed/expanded state now !PREFERENCES_THEME;Theme !TP_COLORAPP_FREE;Free temp+green + CAT02 + [output] !TP_COLORAPP_NEUTRAL;Reset !TP_COLORAPP_NEUTRAL_TIP;Reset all sliders checkbox and curves to their default values -!TP_COLORAPP_TEMP_TOOLTIP;To select an illuminant always Tint=1.\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\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504 !TP_COLORAPP_YB;Yb% (mean luminance) !TP_COLORAPP_YBSCENE;Yb% (mean luminance) !TP_COLORAPP_YBSCENE_TOOLTIP;if auto enable, Yb is calculated from the mean value of actual image luminance diff --git a/rtdata/languages/Greek b/rtdata/languages/Greek index f3dbcca91..4ffc14338 100644 --- a/rtdata/languages/Greek +++ b/rtdata/languages/Greek @@ -462,6 +462,7 @@ TP_WBALANCE_TEMPERATURE;Θερμοκρασία !EXIFFILTER_EXPOSURECOMPENSATION;Exposure compensation (EV) !EXIFFILTER_FILETYPE;File type !EXIFFILTER_METADATAFILTER;Enable metadata filters +!EXIFPANEL_SHOWALL;Show all !EXPORT_BYPASS;Processing steps to bypass !EXPORT_BYPASS_ALL;Select / Unselect All !EXPORT_BYPASS_DEFRINGE;Bypass Defringe @@ -584,7 +585,7 @@ TP_WBALANCE_TEMPERATURE;Θερμοκρασία !HISTORY_MSG_82;Profile changed !HISTORY_MSG_83;S/H - Sharp mask !HISTORY_MSG_84;Perspective correction -!HISTORY_MSG_85;LCP +!HISTORY_MSG_85;Lens Correction - LCP file !HISTORY_MSG_86;RGB Curves - Luminosity mode !HISTORY_MSG_87;Impulse Noise Reduction !HISTORY_MSG_88;Impulse NR threshold @@ -967,6 +968,12 @@ TP_WBALANCE_TEMPERATURE;Θερμοκρασία !HISTORY_MSG_482;CAM02 - Green scene !HISTORY_MSG_483;CAM02 - Yb scene !HISTORY_MSG_484;CAM02 - Auto Yb scene +!HISTORY_MSG_485;Lens Correction +!HISTORY_MSG_486;Lens Correction - Camera +!HISTORY_MSG_487;Lens Correction - Lens +!HISTORY_MSG_488;HDR Tone Mapping +!HISTORY_MSG_489;HDR TM - Threshold +!HISTORY_MSG_490;HDR TM - Amount !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider. !IPTCPANEL_CITYHINT;Enter the name of the city pictured in this image. @@ -993,6 +1000,10 @@ TP_WBALANCE_TEMPERATURE;Θερμοκρασία !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. +!LENSPROFILE_CORRECTION_AUTOMATCH;Auto-matched correction parameters +!LENSPROFILE_CORRECTION_LCPFILE;LCP File +!LENSPROFILE_CORRECTION_MANUAL;Manual correction parameters +!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. !MAIN_BUTTON_FULLSCREEN;Fullscreen !MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the next image relative to image opened in the Editor.\nShortcut: Shift-F4\n\nTo navigate to the next image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F4 !MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the previous image relative to image opened in the Editor.\nShortcut: Shift-F3\n\nTo navigate to the previous image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F3 @@ -1028,6 +1039,7 @@ TP_WBALANCE_TEMPERATURE;Θερμοκρασία !MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 9 !MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 !MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 9 +!MAIN_TOOLTIP_BACKCOLOR3;Background color of the preview: Middle grey\nShortcut: 9 !MAIN_TOOLTIP_BEFOREAFTERLOCK;Lock / Unlock the Before view\n\nLock: keep the Before view unchanged.\nUseful to evaluate the cumulative effect of multiple tools.\nAdditionally, comparisons can be made to any state in the History.\n\nUnlock: the Before view will follow the After view one step behind, showing the image before the effect of the currently used tool. !MAIN_TOOLTIP_PREVIEWB;Preview the Blue channel.\nShortcut: b !MAIN_TOOLTIP_PREVIEWFOCUSMASK;Preview the Focus Mask.\nShortcut: Shift-f\n\nMore accurate on images with shallow depth of field, low noise and at higher zoom levels.\n\nTo improve detection accuracy for noisy images evaluate at smaller zoom, about 10-30%. @@ -1078,7 +1090,7 @@ TP_WBALANCE_TEMPERATURE;Θερμοκρασία !PARTIALPASTE_HSVEQUALIZER;HSV equalizer !PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction !PARTIALPASTE_LABCURVE;L*a*b* adjustments -!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_LENSPROFILE;Profiled lens correction !PARTIALPASTE_PCVIGNETTE;Vignette filter !PARTIALPASTE_PERSPECTIVE;Perspective !PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter @@ -1098,11 +1110,12 @@ TP_WBALANCE_TEMPERATURE;Θερμοκρασία !PARTIALPASTE_RAW_FALSECOLOR;False color suppression !PARTIALPASTE_RAW_IMAGENUM;Sub-image !PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps -!PARTIALPASTE_RAW_PIXELSHIFT;PixelShift +!PARTIALPASTE_RAW_PIXELSHIFT;Pixel Shift !PARTIALPASTE_RETINEX;Retinex !PARTIALPASTE_RGBCURVES;RGB curves !PARTIALPASTE_SHARPENEDGE;Edges !PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_TM_FATTAL;HDR Tone mapping !PARTIALPASTE_VIBRANCE;Vibrance !PARTIALPASTE_WAVELETGROUP;Wavelet Levels !PREFERENCES_ADD;Add @@ -1112,6 +1125,7 @@ TP_WBALANCE_TEMPERATURE;Θερμοκρασία !PREFERENCES_AUTLISVLOW;None !PREFERENCES_AUTLOW;Low !PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +!PREFERENCES_AUTOSAVE_TP_OPEN;Automatically save tools collapsed/expanded\nstate before exiting !PREFERENCES_AUTSTD;Standard !PREFERENCES_BATCH_PROCESSING;Batch Processing !PREFERENCES_BEHADDALL;All to 'Add' @@ -1145,18 +1159,16 @@ TP_WBALANCE_TEMPERATURE;Θερμοκρασία !PREFERENCES_D55;5500K !PREFERENCES_D60;6000K !PREFERENCES_D65;6500K -!PREFERENCES_DARKFRAME;Dark-Frame !PREFERENCES_DARKFRAMEFOUND;Found !PREFERENCES_DARKFRAMESHOTS;shots !PREFERENCES_DARKFRAMETEMPLATES;templates !PREFERENCES_DAUB_LABEL;Use Daubechies D6 wavelets instead of D4 !PREFERENCES_DAUB_TOOLTIP;The Noise Reduction and Wavelet Levels tools use a Debauchies mother wavelet. If you choose D6 instead of D4 you increase the number of orthogonal Daubechies coefficients and probably increase quality of small-scale levels. There is no memory or processing time difference between the two. !PREFERENCES_DIRDARKFRAMES;Dark-frames directory +!PREFERENCES_DIRECTORIES;Directories !PREFERENCES_EDITORLAYOUT;Editor Layout !PREFERENCES_EXPAUT;Expert !PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar\n(de-select for low resolution display) -!PREFERENCES_FILMSIMULATION;Film Simulation -!PREFERENCES_FLATFIELD;Flat-Field !PREFERENCES_FLATFIELDFOUND;Found !PREFERENCES_FLATFIELDSDIR;Flat-fields directory !PREFERENCES_FLATFIELDSHOTS;shots @@ -1232,6 +1244,7 @@ TP_WBALANCE_TEMPERATURE;Θερμοκρασία !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_RGBDTL_LABEL;Max number of threads for Noise Reduction and Wavelet Levels !PREFERENCES_RGBDTL_TOOLTIP;Leave the setting at "0" to automatically use as many threads as possible. The more threads run in parallel, the faster the computation. Refer to RawPedia for memory requirements. +!PREFERENCES_SAVE_TP_OPEN_NOW;Save tools collapsed/expanded state now !PREFERENCES_SELECTFONT;Select main font !PREFERENCES_SELECTFONT_COLPICKER;Select Color Picker's font !PREFERENCES_SERIALIZE_TIFF_READ;Tiff Read Settings @@ -1281,6 +1294,15 @@ TP_WBALANCE_TEMPERATURE;Θερμοκρασία !PROGRESSBAR_PROCESSING_PROFILESAVED;Processing profile saved !PROGRESSBAR_SNAPSHOT_ADDED;Snapshot added !PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!QINFO_FRAMECOUNT;%2 frames +!QINFO_HDR;HDR / %2 frame(s) +!QINFO_PIXELSHIFT;Pixel Shift / %2 frame(s) +!SAMPLEFORMAT_0;Unknown data format +!SAMPLEFORMAT_1;Unsigned 8 bits +!SAMPLEFORMAT_2;Unsigned 16 bits +!SAMPLEFORMAT_4;LogLuv 24 bits +!SAMPLEFORMAT_8;LogLuv 32 bits +!SAMPLEFORMAT_16;32 bits floating point !SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists !SAVEDLG_FORCEFORMATOPTS;Force saving options !SAVEDLG_SUBSAMP;Subsampling @@ -1291,8 +1313,8 @@ TP_WBALANCE_TEMPERATURE;Θερμοκρασία !SAVEDLG_TIFFUNCOMPRESSED;Uncompressed TIFF !SAVEDLG_WARNFILENAME;File will be named !SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. -!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the output profile. -!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate de rendering generated by the output profile of the ICM tool. Most useful for simulating printing outputs. +!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the Printer profile. +!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate the printer's output by using the Printer profile set in Preferences > Color Management. !THRESHOLDSELECTOR_B;Bottom !THRESHOLDSELECTOR_BL;Bottom-left !THRESHOLDSELECTOR_BR;Bottom-right @@ -1437,7 +1459,7 @@ TP_WBALANCE_TEMPERATURE;Θερμοκρασία !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 Tint=1.\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\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504 !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_WBCAM;WB [RT+CAT02] + [output] @@ -1701,7 +1723,7 @@ TP_WBALANCE_TEMPERATURE;Θερμοκρασία !TP_LENSGEOM_AUTOCROP;Auto-Crop !TP_LENSGEOM_FILL;Auto-fill !TP_LENSGEOM_LABEL;Lens / Geometry -!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_LABEL;Profiled Lens Correction !TP_LENSPROFILE_USECA;Chromatic aberration correction !TP_LENSPROFILE_USEDIST;Distortion correction !TP_LENSPROFILE_USEVIGN;Vignetting correction @@ -1924,6 +1946,9 @@ TP_WBALANCE_TEMPERATURE;Θερμοκρασία !TP_SHARPENMICRO_LABEL;Microcontrast !TP_SHARPENMICRO_MATRIX;3×3 matrix instead of 5×5 !TP_SHARPENMICRO_UNIFORMITY;Uniformity +!TP_TM_FATTAL_AMOUNT;Amount +!TP_TM_FATTAL_LABEL;HDR Tone Mapping +!TP_TM_FATTAL_THRESHOLD;Threshold !TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift !TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH !TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones diff --git a/rtdata/languages/Hebrew b/rtdata/languages/Hebrew index d7821b45c..ef8717fa3 100644 --- a/rtdata/languages/Hebrew +++ b/rtdata/languages/Hebrew @@ -463,6 +463,7 @@ TP_WBALANCE_TEMPERATURE;מידת חום !EXIFFILTER_EXPOSURECOMPENSATION;Exposure compensation (EV) !EXIFFILTER_FILETYPE;File type !EXIFFILTER_METADATAFILTER;Enable metadata filters +!EXIFPANEL_SHOWALL;Show all !EXPORT_BYPASS;Processing steps to bypass !EXPORT_BYPASS_ALL;Select / Unselect All !EXPORT_BYPASS_DEFRINGE;Bypass Defringe @@ -585,7 +586,7 @@ TP_WBALANCE_TEMPERATURE;מידת חום !HISTORY_MSG_82;Profile changed !HISTORY_MSG_83;S/H - Sharp mask !HISTORY_MSG_84;Perspective correction -!HISTORY_MSG_85;LCP +!HISTORY_MSG_85;Lens Correction - LCP file !HISTORY_MSG_86;RGB Curves - Luminosity mode !HISTORY_MSG_87;Impulse Noise Reduction !HISTORY_MSG_88;Impulse NR threshold @@ -968,6 +969,12 @@ TP_WBALANCE_TEMPERATURE;מידת חום !HISTORY_MSG_482;CAM02 - Green scene !HISTORY_MSG_483;CAM02 - Yb scene !HISTORY_MSG_484;CAM02 - Auto Yb scene +!HISTORY_MSG_485;Lens Correction +!HISTORY_MSG_486;Lens Correction - Camera +!HISTORY_MSG_487;Lens Correction - Lens +!HISTORY_MSG_488;HDR Tone Mapping +!HISTORY_MSG_489;HDR TM - Threshold +!HISTORY_MSG_490;HDR TM - Amount !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider. !IPTCPANEL_CITYHINT;Enter the name of the city pictured in this image. @@ -994,6 +1001,10 @@ TP_WBALANCE_TEMPERATURE;מידת חום !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. +!LENSPROFILE_CORRECTION_AUTOMATCH;Auto-matched correction parameters +!LENSPROFILE_CORRECTION_LCPFILE;LCP File +!LENSPROFILE_CORRECTION_MANUAL;Manual correction parameters +!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. !MAIN_BUTTON_FULLSCREEN;Fullscreen !MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the next image relative to image opened in the Editor.\nShortcut: Shift-F4\n\nTo navigate to the next image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F4 !MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the previous image relative to image opened in the Editor.\nShortcut: Shift-F3\n\nTo navigate to the previous image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F3 @@ -1029,6 +1040,7 @@ TP_WBALANCE_TEMPERATURE;מידת חום !MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 9 !MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 !MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 9 +!MAIN_TOOLTIP_BACKCOLOR3;Background color of the preview: Middle grey\nShortcut: 9 !MAIN_TOOLTIP_BEFOREAFTERLOCK;Lock / Unlock the Before view\n\nLock: keep the Before view unchanged.\nUseful to evaluate the cumulative effect of multiple tools.\nAdditionally, comparisons can be made to any state in the History.\n\nUnlock: the Before view will follow the After view one step behind, showing the image before the effect of the currently used tool. !MAIN_TOOLTIP_PREVIEWB;Preview the Blue channel.\nShortcut: b !MAIN_TOOLTIP_PREVIEWFOCUSMASK;Preview the Focus Mask.\nShortcut: Shift-f\n\nMore accurate on images with shallow depth of field, low noise and at higher zoom levels.\n\nTo improve detection accuracy for noisy images evaluate at smaller zoom, about 10-30%. @@ -1079,7 +1091,7 @@ TP_WBALANCE_TEMPERATURE;מידת חום !PARTIALPASTE_HSVEQUALIZER;HSV equalizer !PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction !PARTIALPASTE_LABCURVE;L*a*b* adjustments -!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_LENSPROFILE;Profiled lens correction !PARTIALPASTE_PCVIGNETTE;Vignette filter !PARTIALPASTE_PERSPECTIVE;Perspective !PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter @@ -1099,11 +1111,12 @@ TP_WBALANCE_TEMPERATURE;מידת חום !PARTIALPASTE_RAW_FALSECOLOR;False color suppression !PARTIALPASTE_RAW_IMAGENUM;Sub-image !PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps -!PARTIALPASTE_RAW_PIXELSHIFT;PixelShift +!PARTIALPASTE_RAW_PIXELSHIFT;Pixel Shift !PARTIALPASTE_RETINEX;Retinex !PARTIALPASTE_RGBCURVES;RGB curves !PARTIALPASTE_SHARPENEDGE;Edges !PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_TM_FATTAL;HDR Tone mapping !PARTIALPASTE_VIBRANCE;Vibrance !PARTIALPASTE_WAVELETGROUP;Wavelet Levels !PREFERENCES_ADD;Add @@ -1113,6 +1126,7 @@ TP_WBALANCE_TEMPERATURE;מידת חום !PREFERENCES_AUTLISVLOW;None !PREFERENCES_AUTLOW;Low !PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +!PREFERENCES_AUTOSAVE_TP_OPEN;Automatically save tools collapsed/expanded\nstate before exiting !PREFERENCES_AUTSTD;Standard !PREFERENCES_BATCH_PROCESSING;Batch Processing !PREFERENCES_BEHADDALL;All to 'Add' @@ -1146,18 +1160,16 @@ TP_WBALANCE_TEMPERATURE;מידת חום !PREFERENCES_D55;5500K !PREFERENCES_D60;6000K !PREFERENCES_D65;6500K -!PREFERENCES_DARKFRAME;Dark-Frame !PREFERENCES_DARKFRAMEFOUND;Found !PREFERENCES_DARKFRAMESHOTS;shots !PREFERENCES_DARKFRAMETEMPLATES;templates !PREFERENCES_DAUB_LABEL;Use Daubechies D6 wavelets instead of D4 !PREFERENCES_DAUB_TOOLTIP;The Noise Reduction and Wavelet Levels tools use a Debauchies mother wavelet. If you choose D6 instead of D4 you increase the number of orthogonal Daubechies coefficients and probably increase quality of small-scale levels. There is no memory or processing time difference between the two. !PREFERENCES_DIRDARKFRAMES;Dark-frames directory +!PREFERENCES_DIRECTORIES;Directories !PREFERENCES_EDITORLAYOUT;Editor Layout !PREFERENCES_EXPAUT;Expert !PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar\n(de-select for low resolution display) -!PREFERENCES_FILMSIMULATION;Film Simulation -!PREFERENCES_FLATFIELD;Flat-Field !PREFERENCES_FLATFIELDFOUND;Found !PREFERENCES_FLATFIELDSDIR;Flat-fields directory !PREFERENCES_FLATFIELDSHOTS;shots @@ -1233,6 +1245,7 @@ TP_WBALANCE_TEMPERATURE;מידת חום !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_RGBDTL_LABEL;Max number of threads for Noise Reduction and Wavelet Levels !PREFERENCES_RGBDTL_TOOLTIP;Leave the setting at "0" to automatically use as many threads as possible. The more threads run in parallel, the faster the computation. Refer to RawPedia for memory requirements. +!PREFERENCES_SAVE_TP_OPEN_NOW;Save tools collapsed/expanded state now !PREFERENCES_SELECTFONT;Select main font !PREFERENCES_SELECTFONT_COLPICKER;Select Color Picker's font !PREFERENCES_SERIALIZE_TIFF_READ;Tiff Read Settings @@ -1282,6 +1295,15 @@ TP_WBALANCE_TEMPERATURE;מידת חום !PROGRESSBAR_PROCESSING_PROFILESAVED;Processing profile saved !PROGRESSBAR_SNAPSHOT_ADDED;Snapshot added !PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!QINFO_FRAMECOUNT;%2 frames +!QINFO_HDR;HDR / %2 frame(s) +!QINFO_PIXELSHIFT;Pixel Shift / %2 frame(s) +!SAMPLEFORMAT_0;Unknown data format +!SAMPLEFORMAT_1;Unsigned 8 bits +!SAMPLEFORMAT_2;Unsigned 16 bits +!SAMPLEFORMAT_4;LogLuv 24 bits +!SAMPLEFORMAT_8;LogLuv 32 bits +!SAMPLEFORMAT_16;32 bits floating point !SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists !SAVEDLG_FORCEFORMATOPTS;Force saving options !SAVEDLG_SUBSAMP;Subsampling @@ -1292,8 +1314,8 @@ TP_WBALANCE_TEMPERATURE;מידת חום !SAVEDLG_TIFFUNCOMPRESSED;Uncompressed TIFF !SAVEDLG_WARNFILENAME;File will be named !SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. -!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the output profile. -!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate de rendering generated by the output profile of the ICM tool. Most useful for simulating printing outputs. +!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the Printer profile. +!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate the printer's output by using the Printer profile set in Preferences > Color Management. !THRESHOLDSELECTOR_B;Bottom !THRESHOLDSELECTOR_BL;Bottom-left !THRESHOLDSELECTOR_BR;Bottom-right @@ -1438,7 +1460,7 @@ TP_WBALANCE_TEMPERATURE;מידת חום !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 Tint=1.\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\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504 !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_WBCAM;WB [RT+CAT02] + [output] @@ -1702,7 +1724,7 @@ TP_WBALANCE_TEMPERATURE;מידת חום !TP_LENSGEOM_AUTOCROP;Auto-Crop !TP_LENSGEOM_FILL;Auto-fill !TP_LENSGEOM_LABEL;Lens / Geometry -!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_LABEL;Profiled Lens Correction !TP_LENSPROFILE_USECA;Chromatic aberration correction !TP_LENSPROFILE_USEDIST;Distortion correction !TP_LENSPROFILE_USEVIGN;Vignetting correction @@ -1925,6 +1947,9 @@ TP_WBALANCE_TEMPERATURE;מידת חום !TP_SHARPENMICRO_LABEL;Microcontrast !TP_SHARPENMICRO_MATRIX;3×3 matrix instead of 5×5 !TP_SHARPENMICRO_UNIFORMITY;Uniformity +!TP_TM_FATTAL_AMOUNT;Amount +!TP_TM_FATTAL_LABEL;HDR Tone Mapping +!TP_TM_FATTAL_THRESHOLD;Threshold !TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift !TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH !TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones diff --git a/rtdata/languages/Italiano b/rtdata/languages/Italiano index 2f993423b..034d16928 100644 --- a/rtdata/languages/Italiano +++ b/rtdata/languages/Italiano @@ -661,7 +661,6 @@ PREFERENCES_D50;5000K PREFERENCES_D55;5500K PREFERENCES_D60;6000K PREFERENCES_D65;6500K -PREFERENCES_DARKFRAME;Dark Frame PREFERENCES_DARKFRAMEFOUND;Trovati PREFERENCES_DARKFRAMESHOTS;fotogrammi PREFERENCES_DARKFRAMETEMPLATES;modelli @@ -679,7 +678,6 @@ PREFERENCES_EXTERNALEDITOR;Programma di ritocco esterni PREFERENCES_FBROWSEROPTS;Opzioni del Navigatore e delle miniature PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Barra di navigazione a singola riga (deseleziona nel caso di schermo a bassa risoluzione) PREFERENCES_FILEFORMAT;Formato file -PREFERENCES_FLATFIELD;Flat Field PREFERENCES_FLATFIELDFOUND;Trovati PREFERENCES_FLATFIELDSDIR;Cartella dei fotogrammi di campo (Flat Field) PREFERENCES_FLATFIELDSHOTS;fotogrammi @@ -1346,6 +1344,7 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !DYNPROFILEEDITOR_NEW;New !DYNPROFILEEDITOR_NEW_RULE;New Dynamic Profile Rule !DYNPROFILEEDITOR_PROFILE;Processing Profile +!EXIFPANEL_SHOWALL;Show all !EXPORT_BYPASS;Processing steps to bypass !EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels !EXPORT_PIPELINE;Processing pipeline @@ -1580,6 +1579,12 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !HISTORY_MSG_482;CAM02 - Green scene !HISTORY_MSG_483;CAM02 - Yb scene !HISTORY_MSG_484;CAM02 - Auto Yb scene +!HISTORY_MSG_485;Lens Correction +!HISTORY_MSG_486;Lens Correction - Camera +!HISTORY_MSG_487;Lens Correction - Lens +!HISTORY_MSG_488;HDR Tone Mapping +!HISTORY_MSG_489;HDR TM - Threshold +!HISTORY_MSG_490;HDR TM - Amount !IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider. !IPTCPANEL_CITYHINT;Enter the name of the city pictured in this image. !IPTCPANEL_COPYRIGHT;Copyright notice @@ -1605,11 +1610,16 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !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. +!LENSPROFILE_CORRECTION_AUTOMATCH;Auto-matched correction parameters +!LENSPROFILE_CORRECTION_LCPFILE;LCP File +!LENSPROFILE_CORRECTION_MANUAL;Manual correction parameters +!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. !MAIN_BUTTON_SENDTOEDITOR;Edit image in external editor !MAIN_MSG_TOOMANYOPENEDITORS;Too many open editors.\nPlease close an editor to continue. !MAIN_TAB_INSPECT; Inspect !MAIN_TAB_WAVELET;Wavelet !MAIN_TAB_WAVELET_TOOLTIP;Shortcut: Alt-w +!MAIN_TOOLTIP_BACKCOLOR3;Background color of the preview: Middle grey\nShortcut: 9 !MONITOR_PROFILE_SYSTEM;System default !PARTIALPASTE_COLORTONING;Color toning !PARTIALPASTE_EQUALIZER;Wavelet levels @@ -1620,14 +1630,16 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !PARTIALPASTE_PRSHARPENING;Post-resize sharpening !PARTIALPASTE_RAWCACORR_CAREDBLUE;CA red & blue !PARTIALPASTE_RAW_IMAGENUM;Sub-image -!PARTIALPASTE_RAW_PIXELSHIFT;PixelShift +!PARTIALPASTE_RAW_PIXELSHIFT;Pixel Shift !PARTIALPASTE_RETINEX;Retinex +!PARTIALPASTE_TM_FATTAL;HDR Tone mapping !PARTIALPASTE_WAVELETGROUP;Wavelet Levels !PREFERENCES_AUTLISLOW;Low !PREFERENCES_AUTLISMAX;Max - Average of all tiles !PREFERENCES_AUTLISSTD;High !PREFERENCES_AUTLISVLOW;None !PREFERENCES_AUTLOW;Low +!PREFERENCES_AUTOSAVE_TP_OPEN;Automatically save tools collapsed/expanded\nstate before exiting !PREFERENCES_AUTSTD;Standard !PREFERENCES_CIEART_FRAME;CIECAM02-Specific Settings !PREFERENCES_CLUTSCACHE;HaldCLUT Cache @@ -1642,8 +1654,8 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !PREFERENCES_D50_OLD;5000K !PREFERENCES_DAUB_LABEL;Use Daubechies D6 wavelets instead of D4 !PREFERENCES_DAUB_TOOLTIP;The Noise Reduction and Wavelet Levels tools use a Debauchies mother wavelet. If you choose D6 instead of D4 you increase the number of orthogonal Daubechies coefficients and probably increase quality of small-scale levels. There is no memory or processing time difference between the two. +!PREFERENCES_DIRECTORIES;Directories !PREFERENCES_EXPAUT;Expert -!PREFERENCES_FILMSIMULATION;Film Simulation !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_GREY18_OLD;Yb=18 CIE L#50 @@ -1683,6 +1695,7 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !PREFERENCES_PRTPROFILE;Color profile !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 tools collapsed/expanded state now !PREFERENCES_SELECTFONT_COLPICKER;Select Color Picker's font !PREFERENCES_SERIALIZE_TIFF_READ;Tiff Read Settings !PREFERENCES_SERIALIZE_TIFF_READ_LABEL;Serialize read of tiff files @@ -1702,9 +1715,18 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !PREFERENCES_WLTWO;Two levels !PREFERENCES_WLZER;No !PROFILEPANEL_PDYNAMIC;Dynamic +!QINFO_FRAMECOUNT;%2 frames +!QINFO_HDR;HDR / %2 frame(s) +!QINFO_PIXELSHIFT;Pixel Shift / %2 frame(s) +!SAMPLEFORMAT_0;Unknown data format +!SAMPLEFORMAT_1;Unsigned 8 bits +!SAMPLEFORMAT_2;Unsigned 16 bits +!SAMPLEFORMAT_4;LogLuv 24 bits +!SAMPLEFORMAT_8;LogLuv 32 bits +!SAMPLEFORMAT_16;32 bits 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;If active, indicates in grey the pixels which have out of gamut colors from the output profile. -!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate de rendering generated by the output profile of the ICM tool. Most useful for simulating printing outputs. +!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the Printer profile. +!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate the printer's output by using the Printer profile set in Preferences > Color Management. !TOOLBAR_TOOLTIP_COLORPICKER;Lockable Color Picker\n\nWhen enabled:\nClick in the preview with left mouse button to add a color picker\nDrag it around while pressing the left mouse button\nDelete the color picker with a right mouse button click\nDelete all color pickers with Shift + Right mouse button click\nRight click away from any color picker to go back to the Hand tool !TP_CBDL_AFT;After Black-and-White !TP_CBDL_BEF;Before Black-and-White @@ -1713,7 +1735,7 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !TP_COLORAPP_FREE;Free temp+green + CAT02 + [output] !TP_COLORAPP_NEUTRAL;Reset !TP_COLORAPP_NEUTRAL_TIP;Reset all sliders checkbox and curves to their default values -!TP_COLORAPP_TEMP_TOOLTIP;To select an illuminant always Tint=1.\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\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504 !TP_COLORAPP_YB;Yb% (mean luminance) !TP_COLORAPP_YBSCENE;Yb% (mean luminance) !TP_COLORAPP_YBSCENE_TOOLTIP;if auto enable, Yb is calculated from the mean value of actual image luminance @@ -1990,6 +2012,9 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !TP_RETINEX_VIEW_TRAN;Transmission - Auto !TP_RETINEX_VIEW_TRAN2;Transmission - Fixed !TP_RETINEX_VIEW_UNSHARP;Unsharp mask +!TP_TM_FATTAL_AMOUNT;Amount +!TP_TM_FATTAL_LABEL;HDR Tone Mapping +!TP_TM_FATTAL_THRESHOLD;Threshold !TP_WAVELET_1;Level 1 !TP_WAVELET_2;Level 2 !TP_WAVELET_3;Level 3 diff --git a/rtdata/languages/Japanese b/rtdata/languages/Japanese index fdd5baad7..ae9ff5b7f 100644 --- a/rtdata/languages/Japanese +++ b/rtdata/languages/Japanese @@ -881,7 +881,6 @@ PREFERENCES_D50;5000K PREFERENCES_D55;5500K PREFERENCES_D60;6000K PREFERENCES_D65;6500K -PREFERENCES_DARKFRAME;ダークフレーム PREFERENCES_DARKFRAMEFOUND;検出 PREFERENCES_DARKFRAMESHOTS;ショット PREFERENCES_DARKFRAMETEMPLATES;テンプレート @@ -902,8 +901,6 @@ PREFERENCES_EXTERNALEDITOR;外部エディタ PREFERENCES_FBROWSEROPTS;ファイルブラウザ/サムネイルのオプション PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;ファイルブラウザでの一行のツールバー (低解像度表示用に選択解除) PREFERENCES_FILEFORMAT;ファイル形式 -PREFERENCES_FILMSIMULATION;フィルムシミュレーション -PREFERENCES_FLATFIELD;フラットフィールド PREFERENCES_FLATFIELDFOUND;検出 PREFERENCES_FLATFIELDSDIR;フラットフィールド・ディレクトリ PREFERENCES_FLATFIELDSHOTS;ショット @@ -1885,6 +1882,7 @@ ZOOMPANEL_ZOOMOUT;ズームアウト\nショートカット: - !DYNPROFILEEDITOR_NEW;New !DYNPROFILEEDITOR_NEW_RULE;New Dynamic Profile Rule !DYNPROFILEEDITOR_PROFILE;Processing Profile +!EXIFPANEL_SHOWALL;Show all !EXPORT_BYPASS;Processing steps to bypass !EXPORT_PIPELINE;Processing pipeline !EXPORT_USE_FAST_PIPELINE;Dedicated (full processing on resized image) @@ -1958,6 +1956,12 @@ ZOOMPANEL_ZOOMOUT;ズームアウト\nショートカット: - !HISTORY_MSG_482;CAM02 - Green scene !HISTORY_MSG_483;CAM02 - Yb scene !HISTORY_MSG_484;CAM02 - Auto Yb scene +!HISTORY_MSG_485;Lens Correction +!HISTORY_MSG_486;Lens Correction - Camera +!HISTORY_MSG_487;Lens Correction - Lens +!HISTORY_MSG_488;HDR Tone Mapping +!HISTORY_MSG_489;HDR TM - Threshold +!HISTORY_MSG_490;HDR TM - Amount !IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider. !IPTCPANEL_CITYHINT;Enter the name of the city pictured in this image. !IPTCPANEL_COPYRIGHT;Copyright notice @@ -1983,16 +1987,24 @@ ZOOMPANEL_ZOOMOUT;ズームアウト\nショートカット: - !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. +!LENSPROFILE_CORRECTION_AUTOMATCH;Auto-matched correction parameters +!LENSPROFILE_CORRECTION_LCPFILE;LCP File +!LENSPROFILE_CORRECTION_MANUAL;Manual correction parameters +!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. !MAIN_BUTTON_SENDTOEDITOR;Edit image in external editor !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 !MONITOR_PROFILE_SYSTEM;System default !PARTIALPASTE_PRSHARPENING;Post-resize sharpening !PARTIALPASTE_RAWCACORR_CAREDBLUE;CA red & blue !PARTIALPASTE_RAW_IMAGENUM;Sub-image -!PARTIALPASTE_RAW_PIXELSHIFT;PixelShift +!PARTIALPASTE_RAW_PIXELSHIFT;Pixel Shift !PARTIALPASTE_RETINEX;Retinex +!PARTIALPASTE_TM_FATTAL;HDR Tone mapping +!PREFERENCES_AUTOSAVE_TP_OPEN;Automatically save tools collapsed/expanded\nstate before exiting !PREFERENCES_CMMBPC;Black point compensation !PREFERENCES_D50_OLD;5000K +!PREFERENCES_DIRECTORIES;Directories !PREFERENCES_GREY18_OLD;Yb=18 CIE L#50 !PREFERENCES_LANG;Language !PREFERENCES_MONINTENT;Default rendering intent @@ -2007,14 +2019,24 @@ ZOOMPANEL_ZOOMOUT;ズームアウト\nショートカット: - !PREFERENCES_PROFILE_NONE;None !PREFERENCES_PRTINTENT;Rendering intent !PREFERENCES_PRTPROFILE;Color profile +!PREFERENCES_SAVE_TP_OPEN_NOW;Save tools collapsed/expanded state now !PREFERENCES_SELECTFONT_COLPICKER;Select Color Picker's font !PREFERENCES_TAB_DYNAMICPROFILE;Dynamic Profile Rules !PREFERENCES_THEME;Theme !PREFERENCES_TUNNELMETADATA;Copy Exif/IPTC/XMP unchanged to output file !PROFILEPANEL_PDYNAMIC;Dynamic +!QINFO_FRAMECOUNT;%2 frames +!QINFO_HDR;HDR / %2 frame(s) +!QINFO_PIXELSHIFT;Pixel Shift / %2 frame(s) +!SAMPLEFORMAT_0;Unknown data format +!SAMPLEFORMAT_1;Unsigned 8 bits +!SAMPLEFORMAT_2;Unsigned 16 bits +!SAMPLEFORMAT_4;LogLuv 24 bits +!SAMPLEFORMAT_8;LogLuv 32 bits +!SAMPLEFORMAT_16;32 bits 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;If active, indicates in grey the pixels which have out of gamut colors from the output profile. -!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate de rendering generated by the output profile of the ICM tool. Most useful for simulating printing outputs. +!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the Printer profile. +!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate the printer's output by using the Printer profile set in Preferences > Color Management. !TOOLBAR_TOOLTIP_COLORPICKER;Lockable Color Picker\n\nWhen enabled:\nClick in the preview with left mouse button to add a color picker\nDrag it around while pressing the left mouse button\nDelete the color picker with a right mouse button click\nDelete all color pickers with Shift + Right mouse button click\nRight click away from any color picker to go back to the Hand tool !TP_CBDL_AFT;After Black-and-White !TP_CBDL_BEF;Before Black-and-White @@ -2023,7 +2045,7 @@ ZOOMPANEL_ZOOMOUT;ズームアウト\nショートカット: - !TP_COLORAPP_FREE;Free temp+green + CAT02 + [output] !TP_COLORAPP_NEUTRAL;Reset !TP_COLORAPP_NEUTRAL_TIP;Reset all sliders checkbox and curves to their default values -!TP_COLORAPP_TEMP_TOOLTIP;To select an illuminant always Tint=1.\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\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504 !TP_COLORAPP_YB;Yb% (mean luminance) !TP_COLORAPP_YBSCENE;Yb% (mean luminance) !TP_COLORAPP_YBSCENE_TOOLTIP;if auto enable, Yb is calculated from the mean value of actual image luminance @@ -2183,5 +2205,8 @@ ZOOMPANEL_ZOOMOUT;ズームアウト\nショートカット: - !TP_RETINEX_VIEW_TRAN;Transmission - Auto !TP_RETINEX_VIEW_TRAN2;Transmission - Fixed !TP_RETINEX_VIEW_UNSHARP;Unsharp mask +!TP_TM_FATTAL_AMOUNT;Amount +!TP_TM_FATTAL_LABEL;HDR Tone Mapping +!TP_TM_FATTAL_THRESHOLD;Threshold !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/Latvian b/rtdata/languages/Latvian index 9a2d837b1..56e1fabb7 100644 --- a/rtdata/languages/Latvian +++ b/rtdata/languages/Latvian @@ -463,6 +463,7 @@ TP_WBALANCE_TEMPERATURE;Temperatūra !EXIFFILTER_EXPOSURECOMPENSATION;Exposure compensation (EV) !EXIFFILTER_FILETYPE;File type !EXIFFILTER_METADATAFILTER;Enable metadata filters +!EXIFPANEL_SHOWALL;Show all !EXPORT_BYPASS;Processing steps to bypass !EXPORT_BYPASS_ALL;Select / Unselect All !EXPORT_BYPASS_DEFRINGE;Bypass Defringe @@ -585,7 +586,7 @@ TP_WBALANCE_TEMPERATURE;Temperatūra !HISTORY_MSG_82;Profile changed !HISTORY_MSG_83;S/H - Sharp mask !HISTORY_MSG_84;Perspective correction -!HISTORY_MSG_85;LCP +!HISTORY_MSG_85;Lens Correction - LCP file !HISTORY_MSG_86;RGB Curves - Luminosity mode !HISTORY_MSG_87;Impulse Noise Reduction !HISTORY_MSG_88;Impulse NR threshold @@ -968,6 +969,12 @@ TP_WBALANCE_TEMPERATURE;Temperatūra !HISTORY_MSG_482;CAM02 - Green scene !HISTORY_MSG_483;CAM02 - Yb scene !HISTORY_MSG_484;CAM02 - Auto Yb scene +!HISTORY_MSG_485;Lens Correction +!HISTORY_MSG_486;Lens Correction - Camera +!HISTORY_MSG_487;Lens Correction - Lens +!HISTORY_MSG_488;HDR Tone Mapping +!HISTORY_MSG_489;HDR TM - Threshold +!HISTORY_MSG_490;HDR TM - Amount !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider. !IPTCPANEL_CITYHINT;Enter the name of the city pictured in this image. @@ -994,6 +1001,10 @@ TP_WBALANCE_TEMPERATURE;Temperatūra !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. +!LENSPROFILE_CORRECTION_AUTOMATCH;Auto-matched correction parameters +!LENSPROFILE_CORRECTION_LCPFILE;LCP File +!LENSPROFILE_CORRECTION_MANUAL;Manual correction parameters +!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. !MAIN_BUTTON_FULLSCREEN;Fullscreen !MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the next image relative to image opened in the Editor.\nShortcut: Shift-F4\n\nTo navigate to the next image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F4 !MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the previous image relative to image opened in the Editor.\nShortcut: Shift-F3\n\nTo navigate to the previous image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F3 @@ -1029,6 +1040,7 @@ TP_WBALANCE_TEMPERATURE;Temperatūra !MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 9 !MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 !MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 9 +!MAIN_TOOLTIP_BACKCOLOR3;Background color of the preview: Middle grey\nShortcut: 9 !MAIN_TOOLTIP_BEFOREAFTERLOCK;Lock / Unlock the Before view\n\nLock: keep the Before view unchanged.\nUseful to evaluate the cumulative effect of multiple tools.\nAdditionally, comparisons can be made to any state in the History.\n\nUnlock: the Before view will follow the After view one step behind, showing the image before the effect of the currently used tool. !MAIN_TOOLTIP_PREVIEWB;Preview the Blue channel.\nShortcut: b !MAIN_TOOLTIP_PREVIEWFOCUSMASK;Preview the Focus Mask.\nShortcut: Shift-f\n\nMore accurate on images with shallow depth of field, low noise and at higher zoom levels.\n\nTo improve detection accuracy for noisy images evaluate at smaller zoom, about 10-30%. @@ -1079,7 +1091,7 @@ TP_WBALANCE_TEMPERATURE;Temperatūra !PARTIALPASTE_HSVEQUALIZER;HSV equalizer !PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction !PARTIALPASTE_LABCURVE;L*a*b* adjustments -!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_LENSPROFILE;Profiled lens correction !PARTIALPASTE_PCVIGNETTE;Vignette filter !PARTIALPASTE_PERSPECTIVE;Perspective !PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter @@ -1099,11 +1111,12 @@ TP_WBALANCE_TEMPERATURE;Temperatūra !PARTIALPASTE_RAW_FALSECOLOR;False color suppression !PARTIALPASTE_RAW_IMAGENUM;Sub-image !PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps -!PARTIALPASTE_RAW_PIXELSHIFT;PixelShift +!PARTIALPASTE_RAW_PIXELSHIFT;Pixel Shift !PARTIALPASTE_RETINEX;Retinex !PARTIALPASTE_RGBCURVES;RGB curves !PARTIALPASTE_SHARPENEDGE;Edges !PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_TM_FATTAL;HDR Tone mapping !PARTIALPASTE_VIBRANCE;Vibrance !PARTIALPASTE_WAVELETGROUP;Wavelet Levels !PREFERENCES_ADD;Add @@ -1113,6 +1126,7 @@ TP_WBALANCE_TEMPERATURE;Temperatūra !PREFERENCES_AUTLISVLOW;None !PREFERENCES_AUTLOW;Low !PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +!PREFERENCES_AUTOSAVE_TP_OPEN;Automatically save tools collapsed/expanded\nstate before exiting !PREFERENCES_AUTSTD;Standard !PREFERENCES_BATCH_PROCESSING;Batch Processing !PREFERENCES_BEHADDALL;All to 'Add' @@ -1146,18 +1160,16 @@ TP_WBALANCE_TEMPERATURE;Temperatūra !PREFERENCES_D55;5500K !PREFERENCES_D60;6000K !PREFERENCES_D65;6500K -!PREFERENCES_DARKFRAME;Dark-Frame !PREFERENCES_DARKFRAMEFOUND;Found !PREFERENCES_DARKFRAMESHOTS;shots !PREFERENCES_DARKFRAMETEMPLATES;templates !PREFERENCES_DAUB_LABEL;Use Daubechies D6 wavelets instead of D4 !PREFERENCES_DAUB_TOOLTIP;The Noise Reduction and Wavelet Levels tools use a Debauchies mother wavelet. If you choose D6 instead of D4 you increase the number of orthogonal Daubechies coefficients and probably increase quality of small-scale levels. There is no memory or processing time difference between the two. !PREFERENCES_DIRDARKFRAMES;Dark-frames directory +!PREFERENCES_DIRECTORIES;Directories !PREFERENCES_EDITORLAYOUT;Editor Layout !PREFERENCES_EXPAUT;Expert !PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar\n(de-select for low resolution display) -!PREFERENCES_FILMSIMULATION;Film Simulation -!PREFERENCES_FLATFIELD;Flat-Field !PREFERENCES_FLATFIELDFOUND;Found !PREFERENCES_FLATFIELDSDIR;Flat-fields directory !PREFERENCES_FLATFIELDSHOTS;shots @@ -1233,6 +1245,7 @@ TP_WBALANCE_TEMPERATURE;Temperatūra !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_RGBDTL_LABEL;Max number of threads for Noise Reduction and Wavelet Levels !PREFERENCES_RGBDTL_TOOLTIP;Leave the setting at "0" to automatically use as many threads as possible. The more threads run in parallel, the faster the computation. Refer to RawPedia for memory requirements. +!PREFERENCES_SAVE_TP_OPEN_NOW;Save tools collapsed/expanded state now !PREFERENCES_SELECTFONT;Select main font !PREFERENCES_SELECTFONT_COLPICKER;Select Color Picker's font !PREFERENCES_SERIALIZE_TIFF_READ;Tiff Read Settings @@ -1282,6 +1295,15 @@ TP_WBALANCE_TEMPERATURE;Temperatūra !PROGRESSBAR_PROCESSING_PROFILESAVED;Processing profile saved !PROGRESSBAR_SNAPSHOT_ADDED;Snapshot added !PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!QINFO_FRAMECOUNT;%2 frames +!QINFO_HDR;HDR / %2 frame(s) +!QINFO_PIXELSHIFT;Pixel Shift / %2 frame(s) +!SAMPLEFORMAT_0;Unknown data format +!SAMPLEFORMAT_1;Unsigned 8 bits +!SAMPLEFORMAT_2;Unsigned 16 bits +!SAMPLEFORMAT_4;LogLuv 24 bits +!SAMPLEFORMAT_8;LogLuv 32 bits +!SAMPLEFORMAT_16;32 bits floating point !SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists !SAVEDLG_FORCEFORMATOPTS;Force saving options !SAVEDLG_SUBSAMP;Subsampling @@ -1292,8 +1314,8 @@ TP_WBALANCE_TEMPERATURE;Temperatūra !SAVEDLG_TIFFUNCOMPRESSED;Uncompressed TIFF !SAVEDLG_WARNFILENAME;File will be named !SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. -!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the output profile. -!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate de rendering generated by the output profile of the ICM tool. Most useful for simulating printing outputs. +!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the Printer profile. +!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate the printer's output by using the Printer profile set in Preferences > Color Management. !THRESHOLDSELECTOR_B;Bottom !THRESHOLDSELECTOR_BL;Bottom-left !THRESHOLDSELECTOR_BR;Bottom-right @@ -1438,7 +1460,7 @@ TP_WBALANCE_TEMPERATURE;Temperatūra !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 Tint=1.\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\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504 !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_WBCAM;WB [RT+CAT02] + [output] @@ -1702,7 +1724,7 @@ TP_WBALANCE_TEMPERATURE;Temperatūra !TP_LENSGEOM_AUTOCROP;Auto-Crop !TP_LENSGEOM_FILL;Auto-fill !TP_LENSGEOM_LABEL;Lens / Geometry -!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_LABEL;Profiled Lens Correction !TP_LENSPROFILE_USECA;Chromatic aberration correction !TP_LENSPROFILE_USEDIST;Distortion correction !TP_LENSPROFILE_USEVIGN;Vignetting correction @@ -1925,6 +1947,9 @@ TP_WBALANCE_TEMPERATURE;Temperatūra !TP_SHARPENMICRO_LABEL;Microcontrast !TP_SHARPENMICRO_MATRIX;3×3 matrix instead of 5×5 !TP_SHARPENMICRO_UNIFORMITY;Uniformity +!TP_TM_FATTAL_AMOUNT;Amount +!TP_TM_FATTAL_LABEL;HDR Tone Mapping +!TP_TM_FATTAL_THRESHOLD;Threshold !TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift !TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH !TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones diff --git a/rtdata/languages/Magyar b/rtdata/languages/Magyar index 2ba03b396..abddd957a 100644 --- a/rtdata/languages/Magyar +++ b/rtdata/languages/Magyar @@ -493,7 +493,6 @@ PREFERENCES_CUSTPROFBUILD;Egyedi profil készítő PREFERENCES_CUSTPROFBUILDHINT;Executable (or script) file called when a new initial profile should be generated for an image.\nReceives command line params to allow a rules based .pp3 generation:\n[Path raw/JPG] [Path default profile] [f-no] [exposure in secs] [focal length in mm] [ISO] [Lens] [Camera] PREFERENCES_CUSTPROFBUILDPATH;Indítóállomány útvonala PREFERENCES_CUTOVERLAYBRUSH;Vágás maszkjának színe/áttetszősége -PREFERENCES_DARKFRAME;Fekete referenciakép (dark frame) PREFERENCES_DARKFRAMEFOUND;Találat PREFERENCES_DARKFRAMESHOTS;kép PREFERENCES_DARKFRAMETEMPLATES;sablonok @@ -511,7 +510,6 @@ PREFERENCES_EXTERNALEDITOR;Külső képszerkesztő program PREFERENCES_FBROWSEROPTS;Állományböngésző beállításai PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Egysoros állományböngésző eszköztár (alacsony felbontás esetén hagyd üresen) PREFERENCES_FILEFORMAT;Állományformátum -PREFERENCES_FLATFIELD;Flat Field PREFERENCES_FLATFIELDFOUND;Találat PREFERENCES_FLATFIELDSDIR;Flat Fields könyvtár PREFERENCES_FLATFIELDSHOTS;kép @@ -891,6 +889,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !DYNPROFILEEDITOR_PROFILE;Processing Profile !EDIT_OBJECT_TOOLTIP;Displays a widget on the preview window which lets you adjust this tool. !EDIT_PIPETTE_TOOLTIP;To add an adjustment point to the curve, hold the Ctrl key while left-clicking the desired spot in the image preview.\nTo adjust the point, hold the Ctrl key while left-clicking the corresponding area in the preview, then let go of Ctrl (unless you desire fine control) and while still holding the left mouse button move the mouse up or down to move that point up or down in the curve. +!EXIFPANEL_SHOWALL;Show all !EXPORT_BYPASS;Processing steps to bypass !EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels !EXPORT_BYPASS_RAW_LMMSE_ITERATIONS;Bypass [raw] LMMSE Enhancement Steps @@ -1243,6 +1242,12 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !HISTORY_MSG_482;CAM02 - Green scene !HISTORY_MSG_483;CAM02 - Yb scene !HISTORY_MSG_484;CAM02 - Auto Yb scene +!HISTORY_MSG_485;Lens Correction +!HISTORY_MSG_486;Lens Correction - Camera +!HISTORY_MSG_487;Lens Correction - Lens +!HISTORY_MSG_488;HDR Tone Mapping +!HISTORY_MSG_489;HDR TM - Threshold +!HISTORY_MSG_490;HDR TM - Amount !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider. !IPTCPANEL_CITYHINT;Enter the name of the city pictured in this image. @@ -1269,6 +1274,10 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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. +!LENSPROFILE_CORRECTION_AUTOMATCH;Auto-matched correction parameters +!LENSPROFILE_CORRECTION_LCPFILE;LCP File +!LENSPROFILE_CORRECTION_MANUAL;Manual correction parameters +!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. !MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the next image relative to image opened in the Editor.\nShortcut: Shift-F4\n\nTo navigate to the next image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F4 !MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the previous image relative to image opened in the Editor.\nShortcut: Shift-F3\n\nTo navigate to the previous image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F3 !MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchronize the File Browser or Filmstrip with the Editor to reveal the thumbnail of the currently opened image, and clear any active filters.\nShortcut: x\n\nAs above, but without clearing active filters:\nShortcut: y\n(Note that the thumbnail of the opened image will not be shown if filtered out). @@ -1284,6 +1293,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 9 !MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 !MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 9 +!MAIN_TOOLTIP_BACKCOLOR3;Background color of the preview: Middle grey\nShortcut: 9 !MONITOR_PROFILE_SYSTEM;System default !NAVIGATOR_B;B: !NAVIGATOR_G;G: @@ -1305,7 +1315,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !PARTIALPASTE_FILMSIMULATION;Film simulation !PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field clip control !PARTIALPASTE_GRADIENT;Graduated filter -!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_LENSPROFILE;Profiled lens correction !PARTIALPASTE_PCVIGNETTE;Vignette filter !PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter !PARTIALPASTE_PREPROCESS_HOTPIXFILT;Hot pixel filter @@ -1313,14 +1323,16 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !PARTIALPASTE_RAWCACORR_CAREDBLUE;CA red & blue !PARTIALPASTE_RAW_IMAGENUM;Sub-image !PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps -!PARTIALPASTE_RAW_PIXELSHIFT;PixelShift +!PARTIALPASTE_RAW_PIXELSHIFT;Pixel Shift !PARTIALPASTE_RETINEX;Retinex +!PARTIALPASTE_TM_FATTAL;HDR Tone mapping !PARTIALPASTE_WAVELETGROUP;Wavelet Levels !PREFERENCES_AUTLISLOW;Low !PREFERENCES_AUTLISMAX;Max - Average of all tiles !PREFERENCES_AUTLISSTD;High !PREFERENCES_AUTLISVLOW;None !PREFERENCES_AUTLOW;Low +!PREFERENCES_AUTOSAVE_TP_OPEN;Automatically save tools collapsed/expanded\nstate before exiting !PREFERENCES_AUTSTD;Standard !PREFERENCES_BEHADDALL;All to 'Add' !PREFERENCES_BEHADDALLHINT;Set all parameters to the Add mode.\nAdjustments of parameters in the batch tool panel will be deltas to the stored values. @@ -1350,8 +1362,8 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !PREFERENCES_D65;6500K !PREFERENCES_DAUB_LABEL;Use Daubechies D6 wavelets instead of D4 !PREFERENCES_DAUB_TOOLTIP;The Noise Reduction and Wavelet Levels tools use a Debauchies mother wavelet. If you choose D6 instead of D4 you increase the number of orthogonal Daubechies coefficients and probably increase quality of small-scale levels. There is no memory or processing time difference between the two. +!PREFERENCES_DIRECTORIES;Directories !PREFERENCES_EXPAUT;Expert -!PREFERENCES_FILMSIMULATION;Film Simulation !PREFERENCES_FLUOF2;Fluorescent F2 !PREFERENCES_FLUOF7;Fluorescent F7 !PREFERENCES_FLUOF11;Fluorescent F11 @@ -1408,6 +1420,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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_RGBDTL_LABEL;Max number of threads for Noise Reduction and Wavelet Levels !PREFERENCES_RGBDTL_TOOLTIP;Leave the setting at "0" to automatically use as many threads as possible. The more threads run in parallel, the faster the computation. Refer to RawPedia for memory requirements. +!PREFERENCES_SAVE_TP_OPEN_NOW;Save tools collapsed/expanded state now !PREFERENCES_SELECTFONT_COLPICKER;Select Color Picker's font !PREFERENCES_SERIALIZE_TIFF_READ;Tiff Read Settings !PREFERENCES_SERIALIZE_TIFF_READ_LABEL;Serialize read of tiff files @@ -1437,6 +1450,15 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !PROGRESSBAR_NOIMAGES;No images found !PROGRESSBAR_PROCESSING_PROFILESAVED;Processing profile saved !PROGRESSBAR_SNAPSHOT_ADDED;Snapshot added +!QINFO_FRAMECOUNT;%2 frames +!QINFO_HDR;HDR / %2 frame(s) +!QINFO_PIXELSHIFT;Pixel Shift / %2 frame(s) +!SAMPLEFORMAT_0;Unknown data format +!SAMPLEFORMAT_1;Unsigned 8 bits +!SAMPLEFORMAT_2;Unsigned 16 bits +!SAMPLEFORMAT_4;LogLuv 24 bits +!SAMPLEFORMAT_8;LogLuv 32 bits +!SAMPLEFORMAT_16;32 bits floating point !SAVEDLG_FORCEFORMATOPTS;Force saving options !SAVEDLG_SUBSAMP;Subsampling !SAVEDLG_SUBSAMP_1;Best compression @@ -1445,8 +1467,8 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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. !SAVEDLG_WARNFILENAME;File will be named !SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. -!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the output profile. -!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate de rendering generated by the output profile of the ICM tool. Most useful for simulating printing outputs. +!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the Printer profile. +!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate the printer's output by using the Printer profile set in Preferences > Color Management. !THRESHOLDSELECTOR_B;Bottom !THRESHOLDSELECTOR_BL;Bottom-left !THRESHOLDSELECTOR_BR;Bottom-right @@ -1590,7 +1612,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !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 Tint=1.\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\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504 !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_WBCAM;WB [RT+CAT02] + [output] @@ -1790,7 +1812,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_LABCURVE_LCREDSK_TIP;If enabled, the LC Curve affects only red and skin-tones.\nIf disabled, it applies to all tones. !TP_LABCURVE_RSTPROTECTION;Red and skin-tones protection !TP_LABCURVE_RSTPRO_TOOLTIP;Works on the Chromaticity slider and the CC curve. -!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_LABEL;Profiled Lens Correction !TP_LENSPROFILE_USECA;Chromatic aberration correction !TP_LENSPROFILE_USEDIST;Distortion correction !TP_LENSPROFILE_USEVIGN;Vignetting correction @@ -1974,6 +1996,9 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_RGBCURVES_LUMAMODE_TOOLTIP;Luminosity mode allows to vary the contribution of R, G and B channels to the luminosity of the image, without altering image color. !TP_SAVEDIALOG_OK_TIP;Shortcut: Ctrl-Enter !TP_SHADOWSHLIGHTS_SHARPMASK;Sharp mask +!TP_TM_FATTAL_AMOUNT;Amount +!TP_TM_FATTAL_LABEL;HDR Tone Mapping +!TP_TM_FATTAL_THRESHOLD;Threshold !TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH !TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones !TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Red/Purple diff --git a/rtdata/languages/Nederlands b/rtdata/languages/Nederlands index 19e0c0130..0ea147eb8 100644 --- a/rtdata/languages/Nederlands +++ b/rtdata/languages/Nederlands @@ -966,7 +966,6 @@ PREFERENCES_D50;5000K PREFERENCES_D55;5500K PREFERENCES_D60;6000K PREFERENCES_D65;6500K -PREFERENCES_DARKFRAME;Donkerframe PREFERENCES_DARKFRAMEFOUND;Gevonden PREFERENCES_DARKFRAMESHOTS;foto's PREFERENCES_DARKFRAMETEMPLATES;sjablonen @@ -987,8 +986,6 @@ PREFERENCES_EXTERNALEDITOR;Externe editor PREFERENCES_FBROWSEROPTS;Opties bestandsnavigator PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Enkele rij navigator werkbalk (de-activeer voor lage resolutie) PREFERENCES_FILEFORMAT;Bestandstype -PREFERENCES_FILMSIMULATION;Film Simuleren -PREFERENCES_FLATFIELD;Vlakveldopname (tbv. vignetteringscorrectie) PREFERENCES_FLATFIELDFOUND;Gevonden PREFERENCES_FLATFIELDSDIR;Vlakveldmap PREFERENCES_FLATFIELDSHOTS;foto's @@ -2140,6 +2137,7 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !!!!!!!!!!!!!!!!!!!!!!!!! !DONT_SHOW_AGAIN;Don't show this message again. +!EXIFPANEL_SHOWALL;Show all !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. !HISTORY_MSG_441;Retinex - Gain transmission !HISTORY_MSG_475;PS - Equalize channel @@ -2152,17 +2150,41 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !HISTORY_MSG_482;CAM02 - Green scene !HISTORY_MSG_483;CAM02 - Yb scene !HISTORY_MSG_484;CAM02 - Auto Yb scene +!HISTORY_MSG_485;Lens Correction +!HISTORY_MSG_486;Lens Correction - Camera +!HISTORY_MSG_487;Lens Correction - Lens +!HISTORY_MSG_488;HDR Tone Mapping +!HISTORY_MSG_489;HDR TM - Threshold +!HISTORY_MSG_490;HDR TM - Amount +!LENSPROFILE_CORRECTION_AUTOMATCH;Auto-matched correction parameters +!LENSPROFILE_CORRECTION_LCPFILE;LCP File +!LENSPROFILE_CORRECTION_MANUAL;Manual correction parameters +!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. !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 +!PARTIALPASTE_TM_FATTAL;HDR Tone mapping +!PREFERENCES_AUTOSAVE_TP_OPEN;Automatically save tools collapsed/expanded\nstate before exiting !PREFERENCES_D50_OLD;5000K +!PREFERENCES_DIRECTORIES;Directories !PREFERENCES_GREY18_OLD;Yb=18 CIE L#50 !PREFERENCES_LANG;Language !PREFERENCES_PROFILESAVEBOTH;Save processing profile both to the cache and next to the input file !PREFERENCES_PROFILESAVELOCATION;Processing profile saving location +!PREFERENCES_SAVE_TP_OPEN_NOW;Save tools collapsed/expanded state now !PREFERENCES_THEME;Theme +!QINFO_FRAMECOUNT;%2 frames +!QINFO_HDR;HDR / %2 frame(s) +!QINFO_PIXELSHIFT;Pixel Shift / %2 frame(s) +!SAMPLEFORMAT_0;Unknown data format +!SAMPLEFORMAT_1;Unsigned 8 bits +!SAMPLEFORMAT_2;Unsigned 16 bits +!SAMPLEFORMAT_4;LogLuv 24 bits +!SAMPLEFORMAT_8;LogLuv 32 bits +!SAMPLEFORMAT_16;32 bits floating point !TP_COLORAPP_FREE;Free temp+green + CAT02 + [output] !TP_COLORAPP_NEUTRAL;Reset !TP_COLORAPP_NEUTRAL_TIP;Reset all sliders checkbox and curves to their default values -!TP_COLORAPP_TEMP_TOOLTIP;To select an illuminant always Tint=1.\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\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504 !TP_COLORAPP_YB;Yb% (mean luminance) !TP_COLORAPP_YBSCENE;Yb% (mean luminance) !TP_COLORAPP_YBSCENE_TOOLTIP;if auto enable, Yb is calculated from the mean value of actual image luminance @@ -2172,4 +2194,7 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !TP_RETINEX_GAINOFFS;Gain and Offset (brightness) !TP_RETINEX_GAINTRANSMISSION;Gain transmission !TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Amplify or reduce transmission map to achieve luminance.\nAbscissa: transmission -min from 0, mean, and values (max).\nOrdinate: gain. +!TP_TM_FATTAL_AMOUNT;Amount +!TP_TM_FATTAL_LABEL;HDR Tone Mapping +!TP_TM_FATTAL_THRESHOLD;Threshold !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 diff --git a/rtdata/languages/Norsk BM b/rtdata/languages/Norsk BM index a29bb08b6..7e68880b8 100644 --- a/rtdata/languages/Norsk BM +++ b/rtdata/languages/Norsk BM @@ -462,6 +462,7 @@ TP_WBALANCE_TEMPERATURE;Temperatur !EXIFFILTER_EXPOSURECOMPENSATION;Exposure compensation (EV) !EXIFFILTER_FILETYPE;File type !EXIFFILTER_METADATAFILTER;Enable metadata filters +!EXIFPANEL_SHOWALL;Show all !EXPORT_BYPASS;Processing steps to bypass !EXPORT_BYPASS_ALL;Select / Unselect All !EXPORT_BYPASS_DEFRINGE;Bypass Defringe @@ -584,7 +585,7 @@ TP_WBALANCE_TEMPERATURE;Temperatur !HISTORY_MSG_82;Profile changed !HISTORY_MSG_83;S/H - Sharp mask !HISTORY_MSG_84;Perspective correction -!HISTORY_MSG_85;LCP +!HISTORY_MSG_85;Lens Correction - LCP file !HISTORY_MSG_86;RGB Curves - Luminosity mode !HISTORY_MSG_87;Impulse Noise Reduction !HISTORY_MSG_88;Impulse NR threshold @@ -967,6 +968,12 @@ TP_WBALANCE_TEMPERATURE;Temperatur !HISTORY_MSG_482;CAM02 - Green scene !HISTORY_MSG_483;CAM02 - Yb scene !HISTORY_MSG_484;CAM02 - Auto Yb scene +!HISTORY_MSG_485;Lens Correction +!HISTORY_MSG_486;Lens Correction - Camera +!HISTORY_MSG_487;Lens Correction - Lens +!HISTORY_MSG_488;HDR Tone Mapping +!HISTORY_MSG_489;HDR TM - Threshold +!HISTORY_MSG_490;HDR TM - Amount !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider. !IPTCPANEL_CITYHINT;Enter the name of the city pictured in this image. @@ -993,6 +1000,10 @@ TP_WBALANCE_TEMPERATURE;Temperatur !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. +!LENSPROFILE_CORRECTION_AUTOMATCH;Auto-matched correction parameters +!LENSPROFILE_CORRECTION_LCPFILE;LCP File +!LENSPROFILE_CORRECTION_MANUAL;Manual correction parameters +!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. !MAIN_BUTTON_FULLSCREEN;Fullscreen !MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the next image relative to image opened in the Editor.\nShortcut: Shift-F4\n\nTo navigate to the next image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F4 !MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the previous image relative to image opened in the Editor.\nShortcut: Shift-F3\n\nTo navigate to the previous image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F3 @@ -1028,6 +1039,7 @@ TP_WBALANCE_TEMPERATURE;Temperatur !MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 9 !MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 !MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 9 +!MAIN_TOOLTIP_BACKCOLOR3;Background color of the preview: Middle grey\nShortcut: 9 !MAIN_TOOLTIP_BEFOREAFTERLOCK;Lock / Unlock the Before view\n\nLock: keep the Before view unchanged.\nUseful to evaluate the cumulative effect of multiple tools.\nAdditionally, comparisons can be made to any state in the History.\n\nUnlock: the Before view will follow the After view one step behind, showing the image before the effect of the currently used tool. !MAIN_TOOLTIP_PREVIEWB;Preview the Blue channel.\nShortcut: b !MAIN_TOOLTIP_PREVIEWFOCUSMASK;Preview the Focus Mask.\nShortcut: Shift-f\n\nMore accurate on images with shallow depth of field, low noise and at higher zoom levels.\n\nTo improve detection accuracy for noisy images evaluate at smaller zoom, about 10-30%. @@ -1078,7 +1090,7 @@ TP_WBALANCE_TEMPERATURE;Temperatur !PARTIALPASTE_HSVEQUALIZER;HSV equalizer !PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction !PARTIALPASTE_LABCURVE;L*a*b* adjustments -!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_LENSPROFILE;Profiled lens correction !PARTIALPASTE_PCVIGNETTE;Vignette filter !PARTIALPASTE_PERSPECTIVE;Perspective !PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter @@ -1098,11 +1110,12 @@ TP_WBALANCE_TEMPERATURE;Temperatur !PARTIALPASTE_RAW_FALSECOLOR;False color suppression !PARTIALPASTE_RAW_IMAGENUM;Sub-image !PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps -!PARTIALPASTE_RAW_PIXELSHIFT;PixelShift +!PARTIALPASTE_RAW_PIXELSHIFT;Pixel Shift !PARTIALPASTE_RETINEX;Retinex !PARTIALPASTE_RGBCURVES;RGB curves !PARTIALPASTE_SHARPENEDGE;Edges !PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_TM_FATTAL;HDR Tone mapping !PARTIALPASTE_VIBRANCE;Vibrance !PARTIALPASTE_WAVELETGROUP;Wavelet Levels !PREFERENCES_ADD;Add @@ -1112,6 +1125,7 @@ TP_WBALANCE_TEMPERATURE;Temperatur !PREFERENCES_AUTLISVLOW;None !PREFERENCES_AUTLOW;Low !PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +!PREFERENCES_AUTOSAVE_TP_OPEN;Automatically save tools collapsed/expanded\nstate before exiting !PREFERENCES_AUTSTD;Standard !PREFERENCES_BATCH_PROCESSING;Batch Processing !PREFERENCES_BEHADDALL;All to 'Add' @@ -1145,18 +1159,16 @@ TP_WBALANCE_TEMPERATURE;Temperatur !PREFERENCES_D55;5500K !PREFERENCES_D60;6000K !PREFERENCES_D65;6500K -!PREFERENCES_DARKFRAME;Dark-Frame !PREFERENCES_DARKFRAMEFOUND;Found !PREFERENCES_DARKFRAMESHOTS;shots !PREFERENCES_DARKFRAMETEMPLATES;templates !PREFERENCES_DAUB_LABEL;Use Daubechies D6 wavelets instead of D4 !PREFERENCES_DAUB_TOOLTIP;The Noise Reduction and Wavelet Levels tools use a Debauchies mother wavelet. If you choose D6 instead of D4 you increase the number of orthogonal Daubechies coefficients and probably increase quality of small-scale levels. There is no memory or processing time difference between the two. !PREFERENCES_DIRDARKFRAMES;Dark-frames directory +!PREFERENCES_DIRECTORIES;Directories !PREFERENCES_EDITORLAYOUT;Editor Layout !PREFERENCES_EXPAUT;Expert !PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar\n(de-select for low resolution display) -!PREFERENCES_FILMSIMULATION;Film Simulation -!PREFERENCES_FLATFIELD;Flat-Field !PREFERENCES_FLATFIELDFOUND;Found !PREFERENCES_FLATFIELDSDIR;Flat-fields directory !PREFERENCES_FLATFIELDSHOTS;shots @@ -1232,6 +1244,7 @@ TP_WBALANCE_TEMPERATURE;Temperatur !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_RGBDTL_LABEL;Max number of threads for Noise Reduction and Wavelet Levels !PREFERENCES_RGBDTL_TOOLTIP;Leave the setting at "0" to automatically use as many threads as possible. The more threads run in parallel, the faster the computation. Refer to RawPedia for memory requirements. +!PREFERENCES_SAVE_TP_OPEN_NOW;Save tools collapsed/expanded state now !PREFERENCES_SELECTFONT;Select main font !PREFERENCES_SELECTFONT_COLPICKER;Select Color Picker's font !PREFERENCES_SERIALIZE_TIFF_READ;Tiff Read Settings @@ -1281,6 +1294,15 @@ TP_WBALANCE_TEMPERATURE;Temperatur !PROGRESSBAR_PROCESSING_PROFILESAVED;Processing profile saved !PROGRESSBAR_SNAPSHOT_ADDED;Snapshot added !PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!QINFO_FRAMECOUNT;%2 frames +!QINFO_HDR;HDR / %2 frame(s) +!QINFO_PIXELSHIFT;Pixel Shift / %2 frame(s) +!SAMPLEFORMAT_0;Unknown data format +!SAMPLEFORMAT_1;Unsigned 8 bits +!SAMPLEFORMAT_2;Unsigned 16 bits +!SAMPLEFORMAT_4;LogLuv 24 bits +!SAMPLEFORMAT_8;LogLuv 32 bits +!SAMPLEFORMAT_16;32 bits floating point !SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists !SAVEDLG_FORCEFORMATOPTS;Force saving options !SAVEDLG_SUBSAMP;Subsampling @@ -1291,8 +1313,8 @@ TP_WBALANCE_TEMPERATURE;Temperatur !SAVEDLG_TIFFUNCOMPRESSED;Uncompressed TIFF !SAVEDLG_WARNFILENAME;File will be named !SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. -!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the output profile. -!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate de rendering generated by the output profile of the ICM tool. Most useful for simulating printing outputs. +!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the Printer profile. +!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate the printer's output by using the Printer profile set in Preferences > Color Management. !THRESHOLDSELECTOR_B;Bottom !THRESHOLDSELECTOR_BL;Bottom-left !THRESHOLDSELECTOR_BR;Bottom-right @@ -1437,7 +1459,7 @@ TP_WBALANCE_TEMPERATURE;Temperatur !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 Tint=1.\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\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504 !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_WBCAM;WB [RT+CAT02] + [output] @@ -1701,7 +1723,7 @@ TP_WBALANCE_TEMPERATURE;Temperatur !TP_LENSGEOM_AUTOCROP;Auto-Crop !TP_LENSGEOM_FILL;Auto-fill !TP_LENSGEOM_LABEL;Lens / Geometry -!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_LABEL;Profiled Lens Correction !TP_LENSPROFILE_USECA;Chromatic aberration correction !TP_LENSPROFILE_USEDIST;Distortion correction !TP_LENSPROFILE_USEVIGN;Vignetting correction @@ -1924,6 +1946,9 @@ TP_WBALANCE_TEMPERATURE;Temperatur !TP_SHARPENMICRO_LABEL;Microcontrast !TP_SHARPENMICRO_MATRIX;3×3 matrix instead of 5×5 !TP_SHARPENMICRO_UNIFORMITY;Uniformity +!TP_TM_FATTAL_AMOUNT;Amount +!TP_TM_FATTAL_LABEL;HDR Tone Mapping +!TP_TM_FATTAL_THRESHOLD;Threshold !TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift !TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH !TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones diff --git a/rtdata/languages/Polish b/rtdata/languages/Polish index d683a1ac5..3c54cc184 100644 --- a/rtdata/languages/Polish +++ b/rtdata/languages/Polish @@ -714,7 +714,6 @@ PREFERENCES_D50;5000K PREFERENCES_D55;5500K PREFERENCES_D60;6000K PREFERENCES_D65;6500K -PREFERENCES_DARKFRAME;Czarna klatka PREFERENCES_DARKFRAMEFOUND;Znaleziono PREFERENCES_DARKFRAMESHOTS;zdjęć(ia) PREFERENCES_DARKFRAMETEMPLATES;szablonów(ny) @@ -732,8 +731,6 @@ PREFERENCES_EXTERNALEDITOR;Zewnętrzny edytor PREFERENCES_FBROWSEROPTS;Opcje przeglądarki plików PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Pojedynczy wiersz paska narzędzi (odznaczyć dla niskich rozdzielczości) PREFERENCES_FILEFORMAT;Format pliku -PREFERENCES_FILMSIMULATION;Symulacja kliszy -PREFERENCES_FLATFIELD;Puste pole PREFERENCES_FLATFIELDFOUND;Znaleziono PREFERENCES_FLATFIELDSDIR;Katalog z pustymi polami PREFERENCES_FLATFIELDSHOTS;kadry @@ -1473,6 +1470,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !DYNPROFILEEDITOR_NEW;New !DYNPROFILEEDITOR_NEW_RULE;New Dynamic Profile Rule !DYNPROFILEEDITOR_PROFILE;Processing Profile +!EXIFPANEL_SHOWALL;Show all !EXPORT_BYPASS;Processing steps to bypass !EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels !EXPORT_PIPELINE;Processing pipeline @@ -1664,6 +1662,12 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !HISTORY_MSG_482;CAM02 - Green scene !HISTORY_MSG_483;CAM02 - Yb scene !HISTORY_MSG_484;CAM02 - Auto Yb scene +!HISTORY_MSG_485;Lens Correction +!HISTORY_MSG_486;Lens Correction - Camera +!HISTORY_MSG_487;Lens Correction - Lens +!HISTORY_MSG_488;HDR Tone Mapping +!HISTORY_MSG_489;HDR TM - Threshold +!HISTORY_MSG_490;HDR TM - Amount !IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider. !IPTCPANEL_CITYHINT;Enter the name of the city pictured in this image. !IPTCPANEL_COPYRIGHT;Copyright notice @@ -1689,24 +1693,31 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !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. +!LENSPROFILE_CORRECTION_AUTOMATCH;Auto-matched correction parameters +!LENSPROFILE_CORRECTION_LCPFILE;LCP File +!LENSPROFILE_CORRECTION_MANUAL;Manual correction parameters +!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. !MAIN_BUTTON_SENDTOEDITOR;Edit image in external editor !MAIN_MSG_TOOMANYOPENEDITORS;Too many open editors.\nPlease close an editor to continue. !MAIN_TAB_INSPECT; Inspect !MAIN_TAB_WAVELET;Wavelet !MAIN_TAB_WAVELET_TOOLTIP;Shortcut: Alt-w +!MAIN_TOOLTIP_BACKCOLOR3;Background color of the preview: Middle grey\nShortcut: 9 !MONITOR_PROFILE_SYSTEM;System default !PARTIALPASTE_EQUALIZER;Wavelet levels !PARTIALPASTE_PRSHARPENING;Post-resize sharpening !PARTIALPASTE_RAWCACORR_CAREDBLUE;CA red & blue !PARTIALPASTE_RAW_IMAGENUM;Sub-image -!PARTIALPASTE_RAW_PIXELSHIFT;PixelShift +!PARTIALPASTE_RAW_PIXELSHIFT;Pixel Shift !PARTIALPASTE_RETINEX;Retinex +!PARTIALPASTE_TM_FATTAL;HDR Tone mapping !PARTIALPASTE_WAVELETGROUP;Wavelet Levels !PREFERENCES_AUTLISLOW;Low !PREFERENCES_AUTLISMAX;Max - Average of all tiles !PREFERENCES_AUTLISSTD;High !PREFERENCES_AUTLISVLOW;None !PREFERENCES_AUTLOW;Low +!PREFERENCES_AUTOSAVE_TP_OPEN;Automatically save tools collapsed/expanded\nstate before exiting !PREFERENCES_AUTSTD;Standard !PREFERENCES_CIEART_FRAME;CIECAM02-Specific Settings !PREFERENCES_CLUTSCACHE;HaldCLUT Cache @@ -1720,6 +1731,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !PREFERENCES_D50_OLD;5000K !PREFERENCES_DAUB_LABEL;Use Daubechies D6 wavelets instead of D4 !PREFERENCES_DAUB_TOOLTIP;The Noise Reduction and Wavelet Levels tools use a Debauchies mother wavelet. If you choose D6 instead of D4 you increase the number of orthogonal Daubechies coefficients and probably increase quality of small-scale levels. There is no memory or processing time difference between the two. +!PREFERENCES_DIRECTORIES;Directories !PREFERENCES_EXPAUT;Expert !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. @@ -1760,6 +1772,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !PREFERENCES_PRTPROFILE;Color profile !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 tools collapsed/expanded state now !PREFERENCES_SELECTFONT_COLPICKER;Select Color Picker's font !PREFERENCES_SERIALIZE_TIFF_READ;Tiff Read Settings !PREFERENCES_SERIALIZE_TIFF_READ_LABEL;Serialize read of tiff files @@ -1779,9 +1792,18 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !PREFERENCES_WLTWO;Two levels !PREFERENCES_WLZER;No !PROFILEPANEL_PDYNAMIC;Dynamic +!QINFO_FRAMECOUNT;%2 frames +!QINFO_HDR;HDR / %2 frame(s) +!QINFO_PIXELSHIFT;Pixel Shift / %2 frame(s) +!SAMPLEFORMAT_0;Unknown data format +!SAMPLEFORMAT_1;Unsigned 8 bits +!SAMPLEFORMAT_2;Unsigned 16 bits +!SAMPLEFORMAT_4;LogLuv 24 bits +!SAMPLEFORMAT_8;LogLuv 32 bits +!SAMPLEFORMAT_16;32 bits 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;If active, indicates in grey the pixels which have out of gamut colors from the output profile. -!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate de rendering generated by the output profile of the ICM tool. Most useful for simulating printing outputs. +!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the Printer profile. +!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate the printer's output by using the Printer profile set in Preferences > Color Management. !TOOLBAR_TOOLTIP_COLORPICKER;Lockable Color Picker\n\nWhen enabled:\nClick in the preview with left mouse button to add a color picker\nDrag it around while pressing the left mouse button\nDelete the color picker with a right mouse button click\nDelete all color pickers with Shift + Right mouse button click\nRight click away from any color picker to go back to the Hand tool !TP_CBDL_AFT;After Black-and-White !TP_CBDL_BEF;Before Black-and-White @@ -1790,7 +1812,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_COLORAPP_FREE;Free temp+green + CAT02 + [output] !TP_COLORAPP_NEUTRAL;Reset !TP_COLORAPP_NEUTRAL_TIP;Reset all sliders checkbox and curves to their default values -!TP_COLORAPP_TEMP_TOOLTIP;To select an illuminant always Tint=1.\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\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504 !TP_COLORAPP_YB;Yb% (mean luminance) !TP_COLORAPP_YBSCENE;Yb% (mean luminance) !TP_COLORAPP_YBSCENE_TOOLTIP;if auto enable, Yb is calculated from the mean value of actual image luminance @@ -1996,6 +2018,9 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_RETINEX_VIEW_TRAN;Transmission - Auto !TP_RETINEX_VIEW_TRAN2;Transmission - Fixed !TP_RETINEX_VIEW_UNSHARP;Unsharp mask +!TP_TM_FATTAL_AMOUNT;Amount +!TP_TM_FATTAL_LABEL;HDR Tone Mapping +!TP_TM_FATTAL_THRESHOLD;Threshold !TP_WAVELET_1;Level 1 !TP_WAVELET_2;Level 2 !TP_WAVELET_3;Level 3 diff --git a/rtdata/languages/Polish (Latin Characters) b/rtdata/languages/Polish (Latin Characters) index 84000eb6e..85b9e3f0b 100644 --- a/rtdata/languages/Polish (Latin Characters) +++ b/rtdata/languages/Polish (Latin Characters) @@ -714,7 +714,6 @@ PREFERENCES_D50;5000K PREFERENCES_D55;5500K PREFERENCES_D60;6000K PREFERENCES_D65;6500K -PREFERENCES_DARKFRAME;Czarna klatka PREFERENCES_DARKFRAMEFOUND;Znaleziono PREFERENCES_DARKFRAMESHOTS;zdjec(ia) PREFERENCES_DARKFRAMETEMPLATES;szablonow(ny) @@ -732,8 +731,6 @@ PREFERENCES_EXTERNALEDITOR;Zewnetrzny edytor PREFERENCES_FBROWSEROPTS;Opcje przegladarki plikow PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Pojedynczy wiersz paska narzedzi (odznaczyc dla niskich rozdzielczosci) PREFERENCES_FILEFORMAT;Format pliku -PREFERENCES_FILMSIMULATION;Symulacja kliszy -PREFERENCES_FLATFIELD;Puste pole PREFERENCES_FLATFIELDFOUND;Znaleziono PREFERENCES_FLATFIELDSDIR;Katalog z pustymi polami PREFERENCES_FLATFIELDSHOTS;kadry @@ -1473,6 +1470,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrot: - !DYNPROFILEEDITOR_NEW;New !DYNPROFILEEDITOR_NEW_RULE;New Dynamic Profile Rule !DYNPROFILEEDITOR_PROFILE;Processing Profile +!EXIFPANEL_SHOWALL;Show all !EXPORT_BYPASS;Processing steps to bypass !EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels !EXPORT_PIPELINE;Processing pipeline @@ -1664,6 +1662,12 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrot: - !HISTORY_MSG_482;CAM02 - Green scene !HISTORY_MSG_483;CAM02 - Yb scene !HISTORY_MSG_484;CAM02 - Auto Yb scene +!HISTORY_MSG_485;Lens Correction +!HISTORY_MSG_486;Lens Correction - Camera +!HISTORY_MSG_487;Lens Correction - Lens +!HISTORY_MSG_488;HDR Tone Mapping +!HISTORY_MSG_489;HDR TM - Threshold +!HISTORY_MSG_490;HDR TM - Amount !IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider. !IPTCPANEL_CITYHINT;Enter the name of the city pictured in this image. !IPTCPANEL_COPYRIGHT;Copyright notice @@ -1689,24 +1693,31 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrot: - !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. +!LENSPROFILE_CORRECTION_AUTOMATCH;Auto-matched correction parameters +!LENSPROFILE_CORRECTION_LCPFILE;LCP File +!LENSPROFILE_CORRECTION_MANUAL;Manual correction parameters +!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. !MAIN_BUTTON_SENDTOEDITOR;Edit image in external editor !MAIN_MSG_TOOMANYOPENEDITORS;Too many open editors.\nPlease close an editor to continue. !MAIN_TAB_INSPECT; Inspect !MAIN_TAB_WAVELET;Wavelet !MAIN_TAB_WAVELET_TOOLTIP;Shortcut: Alt-w +!MAIN_TOOLTIP_BACKCOLOR3;Background color of the preview: Middle grey\nShortcut: 9 !MONITOR_PROFILE_SYSTEM;System default !PARTIALPASTE_EQUALIZER;Wavelet levels !PARTIALPASTE_PRSHARPENING;Post-resize sharpening !PARTIALPASTE_RAWCACORR_CAREDBLUE;CA red & blue !PARTIALPASTE_RAW_IMAGENUM;Sub-image -!PARTIALPASTE_RAW_PIXELSHIFT;PixelShift +!PARTIALPASTE_RAW_PIXELSHIFT;Pixel Shift !PARTIALPASTE_RETINEX;Retinex +!PARTIALPASTE_TM_FATTAL;HDR Tone mapping !PARTIALPASTE_WAVELETGROUP;Wavelet Levels !PREFERENCES_AUTLISLOW;Low !PREFERENCES_AUTLISMAX;Max - Average of all tiles !PREFERENCES_AUTLISSTD;High !PREFERENCES_AUTLISVLOW;None !PREFERENCES_AUTLOW;Low +!PREFERENCES_AUTOSAVE_TP_OPEN;Automatically save tools collapsed/expanded\nstate before exiting !PREFERENCES_AUTSTD;Standard !PREFERENCES_CIEART_FRAME;CIECAM02-Specific Settings !PREFERENCES_CLUTSCACHE;HaldCLUT Cache @@ -1720,6 +1731,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrot: - !PREFERENCES_D50_OLD;5000K !PREFERENCES_DAUB_LABEL;Use Daubechies D6 wavelets instead of D4 !PREFERENCES_DAUB_TOOLTIP;The Noise Reduction and Wavelet Levels tools use a Debauchies mother wavelet. If you choose D6 instead of D4 you increase the number of orthogonal Daubechies coefficients and probably increase quality of small-scale levels. There is no memory or processing time difference between the two. +!PREFERENCES_DIRECTORIES;Directories !PREFERENCES_EXPAUT;Expert !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. @@ -1760,6 +1772,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrot: - !PREFERENCES_PRTPROFILE;Color profile !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 tools collapsed/expanded state now !PREFERENCES_SELECTFONT_COLPICKER;Select Color Picker's font !PREFERENCES_SERIALIZE_TIFF_READ;Tiff Read Settings !PREFERENCES_SERIALIZE_TIFF_READ_LABEL;Serialize read of tiff files @@ -1779,9 +1792,18 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrot: - !PREFERENCES_WLTWO;Two levels !PREFERENCES_WLZER;No !PROFILEPANEL_PDYNAMIC;Dynamic +!QINFO_FRAMECOUNT;%2 frames +!QINFO_HDR;HDR / %2 frame(s) +!QINFO_PIXELSHIFT;Pixel Shift / %2 frame(s) +!SAMPLEFORMAT_0;Unknown data format +!SAMPLEFORMAT_1;Unsigned 8 bits +!SAMPLEFORMAT_2;Unsigned 16 bits +!SAMPLEFORMAT_4;LogLuv 24 bits +!SAMPLEFORMAT_8;LogLuv 32 bits +!SAMPLEFORMAT_16;32 bits 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;If active, indicates in grey the pixels which have out of gamut colors from the output profile. -!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate de rendering generated by the output profile of the ICM tool. Most useful for simulating printing outputs. +!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the Printer profile. +!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate the printer's output by using the Printer profile set in Preferences > Color Management. !TOOLBAR_TOOLTIP_COLORPICKER;Lockable Color Picker\n\nWhen enabled:\nClick in the preview with left mouse button to add a color picker\nDrag it around while pressing the left mouse button\nDelete the color picker with a right mouse button click\nDelete all color pickers with Shift + Right mouse button click\nRight click away from any color picker to go back to the Hand tool !TP_CBDL_AFT;After Black-and-White !TP_CBDL_BEF;Before Black-and-White @@ -1790,7 +1812,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrot: - !TP_COLORAPP_FREE;Free temp+green + CAT02 + [output] !TP_COLORAPP_NEUTRAL;Reset !TP_COLORAPP_NEUTRAL_TIP;Reset all sliders checkbox and curves to their default values -!TP_COLORAPP_TEMP_TOOLTIP;To select an illuminant always Tint=1.\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\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504 !TP_COLORAPP_YB;Yb% (mean luminance) !TP_COLORAPP_YBSCENE;Yb% (mean luminance) !TP_COLORAPP_YBSCENE_TOOLTIP;if auto enable, Yb is calculated from the mean value of actual image luminance @@ -1996,6 +2018,9 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrot: - !TP_RETINEX_VIEW_TRAN;Transmission - Auto !TP_RETINEX_VIEW_TRAN2;Transmission - Fixed !TP_RETINEX_VIEW_UNSHARP;Unsharp mask +!TP_TM_FATTAL_AMOUNT;Amount +!TP_TM_FATTAL_LABEL;HDR Tone Mapping +!TP_TM_FATTAL_THRESHOLD;Threshold !TP_WAVELET_1;Level 1 !TP_WAVELET_2;Level 2 !TP_WAVELET_3;Level 3 diff --git a/rtdata/languages/Portugues (Brasil) b/rtdata/languages/Portugues (Brasil) index eb2fe00a4..661f24483 100644 --- a/rtdata/languages/Portugues (Brasil) +++ b/rtdata/languages/Portugues (Brasil) @@ -463,6 +463,7 @@ TP_WBALANCE_TEMPERATURE;Temperatura !EXIFFILTER_EXPOSURECOMPENSATION;Exposure compensation (EV) !EXIFFILTER_FILETYPE;File type !EXIFFILTER_METADATAFILTER;Enable metadata filters +!EXIFPANEL_SHOWALL;Show all !EXPORT_BYPASS;Processing steps to bypass !EXPORT_BYPASS_ALL;Select / Unselect All !EXPORT_BYPASS_DEFRINGE;Bypass Defringe @@ -585,7 +586,7 @@ TP_WBALANCE_TEMPERATURE;Temperatura !HISTORY_MSG_82;Profile changed !HISTORY_MSG_83;S/H - Sharp mask !HISTORY_MSG_84;Perspective correction -!HISTORY_MSG_85;LCP +!HISTORY_MSG_85;Lens Correction - LCP file !HISTORY_MSG_86;RGB Curves - Luminosity mode !HISTORY_MSG_87;Impulse Noise Reduction !HISTORY_MSG_88;Impulse NR threshold @@ -968,6 +969,12 @@ TP_WBALANCE_TEMPERATURE;Temperatura !HISTORY_MSG_482;CAM02 - Green scene !HISTORY_MSG_483;CAM02 - Yb scene !HISTORY_MSG_484;CAM02 - Auto Yb scene +!HISTORY_MSG_485;Lens Correction +!HISTORY_MSG_486;Lens Correction - Camera +!HISTORY_MSG_487;Lens Correction - Lens +!HISTORY_MSG_488;HDR Tone Mapping +!HISTORY_MSG_489;HDR TM - Threshold +!HISTORY_MSG_490;HDR TM - Amount !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider. !IPTCPANEL_CITYHINT;Enter the name of the city pictured in this image. @@ -994,6 +1001,10 @@ TP_WBALANCE_TEMPERATURE;Temperatura !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. +!LENSPROFILE_CORRECTION_AUTOMATCH;Auto-matched correction parameters +!LENSPROFILE_CORRECTION_LCPFILE;LCP File +!LENSPROFILE_CORRECTION_MANUAL;Manual correction parameters +!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. !MAIN_BUTTON_FULLSCREEN;Fullscreen !MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the next image relative to image opened in the Editor.\nShortcut: Shift-F4\n\nTo navigate to the next image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F4 !MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the previous image relative to image opened in the Editor.\nShortcut: Shift-F3\n\nTo navigate to the previous image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F3 @@ -1029,6 +1040,7 @@ TP_WBALANCE_TEMPERATURE;Temperatura !MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 9 !MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 !MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 9 +!MAIN_TOOLTIP_BACKCOLOR3;Background color of the preview: Middle grey\nShortcut: 9 !MAIN_TOOLTIP_BEFOREAFTERLOCK;Lock / Unlock the Before view\n\nLock: keep the Before view unchanged.\nUseful to evaluate the cumulative effect of multiple tools.\nAdditionally, comparisons can be made to any state in the History.\n\nUnlock: the Before view will follow the After view one step behind, showing the image before the effect of the currently used tool. !MAIN_TOOLTIP_PREVIEWB;Preview the Blue channel.\nShortcut: b !MAIN_TOOLTIP_PREVIEWFOCUSMASK;Preview the Focus Mask.\nShortcut: Shift-f\n\nMore accurate on images with shallow depth of field, low noise and at higher zoom levels.\n\nTo improve detection accuracy for noisy images evaluate at smaller zoom, about 10-30%. @@ -1079,7 +1091,7 @@ TP_WBALANCE_TEMPERATURE;Temperatura !PARTIALPASTE_HSVEQUALIZER;HSV equalizer !PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction !PARTIALPASTE_LABCURVE;L*a*b* adjustments -!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_LENSPROFILE;Profiled lens correction !PARTIALPASTE_PCVIGNETTE;Vignette filter !PARTIALPASTE_PERSPECTIVE;Perspective !PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter @@ -1099,11 +1111,12 @@ TP_WBALANCE_TEMPERATURE;Temperatura !PARTIALPASTE_RAW_FALSECOLOR;False color suppression !PARTIALPASTE_RAW_IMAGENUM;Sub-image !PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps -!PARTIALPASTE_RAW_PIXELSHIFT;PixelShift +!PARTIALPASTE_RAW_PIXELSHIFT;Pixel Shift !PARTIALPASTE_RETINEX;Retinex !PARTIALPASTE_RGBCURVES;RGB curves !PARTIALPASTE_SHARPENEDGE;Edges !PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_TM_FATTAL;HDR Tone mapping !PARTIALPASTE_VIBRANCE;Vibrance !PARTIALPASTE_WAVELETGROUP;Wavelet Levels !PREFERENCES_ADD;Add @@ -1113,6 +1126,7 @@ TP_WBALANCE_TEMPERATURE;Temperatura !PREFERENCES_AUTLISVLOW;None !PREFERENCES_AUTLOW;Low !PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +!PREFERENCES_AUTOSAVE_TP_OPEN;Automatically save tools collapsed/expanded\nstate before exiting !PREFERENCES_AUTSTD;Standard !PREFERENCES_BATCH_PROCESSING;Batch Processing !PREFERENCES_BEHADDALL;All to 'Add' @@ -1146,18 +1160,16 @@ TP_WBALANCE_TEMPERATURE;Temperatura !PREFERENCES_D55;5500K !PREFERENCES_D60;6000K !PREFERENCES_D65;6500K -!PREFERENCES_DARKFRAME;Dark-Frame !PREFERENCES_DARKFRAMEFOUND;Found !PREFERENCES_DARKFRAMESHOTS;shots !PREFERENCES_DARKFRAMETEMPLATES;templates !PREFERENCES_DAUB_LABEL;Use Daubechies D6 wavelets instead of D4 !PREFERENCES_DAUB_TOOLTIP;The Noise Reduction and Wavelet Levels tools use a Debauchies mother wavelet. If you choose D6 instead of D4 you increase the number of orthogonal Daubechies coefficients and probably increase quality of small-scale levels. There is no memory or processing time difference between the two. !PREFERENCES_DIRDARKFRAMES;Dark-frames directory +!PREFERENCES_DIRECTORIES;Directories !PREFERENCES_EDITORLAYOUT;Editor Layout !PREFERENCES_EXPAUT;Expert !PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar\n(de-select for low resolution display) -!PREFERENCES_FILMSIMULATION;Film Simulation -!PREFERENCES_FLATFIELD;Flat-Field !PREFERENCES_FLATFIELDFOUND;Found !PREFERENCES_FLATFIELDSDIR;Flat-fields directory !PREFERENCES_FLATFIELDSHOTS;shots @@ -1233,6 +1245,7 @@ TP_WBALANCE_TEMPERATURE;Temperatura !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_RGBDTL_LABEL;Max number of threads for Noise Reduction and Wavelet Levels !PREFERENCES_RGBDTL_TOOLTIP;Leave the setting at "0" to automatically use as many threads as possible. The more threads run in parallel, the faster the computation. Refer to RawPedia for memory requirements. +!PREFERENCES_SAVE_TP_OPEN_NOW;Save tools collapsed/expanded state now !PREFERENCES_SELECTFONT;Select main font !PREFERENCES_SELECTFONT_COLPICKER;Select Color Picker's font !PREFERENCES_SERIALIZE_TIFF_READ;Tiff Read Settings @@ -1282,6 +1295,15 @@ TP_WBALANCE_TEMPERATURE;Temperatura !PROGRESSBAR_PROCESSING_PROFILESAVED;Processing profile saved !PROGRESSBAR_SNAPSHOT_ADDED;Snapshot added !PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!QINFO_FRAMECOUNT;%2 frames +!QINFO_HDR;HDR / %2 frame(s) +!QINFO_PIXELSHIFT;Pixel Shift / %2 frame(s) +!SAMPLEFORMAT_0;Unknown data format +!SAMPLEFORMAT_1;Unsigned 8 bits +!SAMPLEFORMAT_2;Unsigned 16 bits +!SAMPLEFORMAT_4;LogLuv 24 bits +!SAMPLEFORMAT_8;LogLuv 32 bits +!SAMPLEFORMAT_16;32 bits floating point !SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists !SAVEDLG_FORCEFORMATOPTS;Force saving options !SAVEDLG_SUBSAMP;Subsampling @@ -1292,8 +1314,8 @@ TP_WBALANCE_TEMPERATURE;Temperatura !SAVEDLG_TIFFUNCOMPRESSED;Uncompressed TIFF !SAVEDLG_WARNFILENAME;File will be named !SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. -!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the output profile. -!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate de rendering generated by the output profile of the ICM tool. Most useful for simulating printing outputs. +!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the Printer profile. +!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate the printer's output by using the Printer profile set in Preferences > Color Management. !THRESHOLDSELECTOR_B;Bottom !THRESHOLDSELECTOR_BL;Bottom-left !THRESHOLDSELECTOR_BR;Bottom-right @@ -1438,7 +1460,7 @@ TP_WBALANCE_TEMPERATURE;Temperatura !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 Tint=1.\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\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504 !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_WBCAM;WB [RT+CAT02] + [output] @@ -1702,7 +1724,7 @@ TP_WBALANCE_TEMPERATURE;Temperatura !TP_LENSGEOM_AUTOCROP;Auto-Crop !TP_LENSGEOM_FILL;Auto-fill !TP_LENSGEOM_LABEL;Lens / Geometry -!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_LABEL;Profiled Lens Correction !TP_LENSPROFILE_USECA;Chromatic aberration correction !TP_LENSPROFILE_USEDIST;Distortion correction !TP_LENSPROFILE_USEVIGN;Vignetting correction @@ -1925,6 +1947,9 @@ TP_WBALANCE_TEMPERATURE;Temperatura !TP_SHARPENMICRO_LABEL;Microcontrast !TP_SHARPENMICRO_MATRIX;3×3 matrix instead of 5×5 !TP_SHARPENMICRO_UNIFORMITY;Uniformity +!TP_TM_FATTAL_AMOUNT;Amount +!TP_TM_FATTAL_LABEL;HDR Tone Mapping +!TP_TM_FATTAL_THRESHOLD;Threshold !TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift !TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH !TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones diff --git a/rtdata/languages/Russian b/rtdata/languages/Russian index 8d580c3fc..a67674975 100644 --- a/rtdata/languages/Russian +++ b/rtdata/languages/Russian @@ -645,7 +645,6 @@ PREFERENCES_D50;5000K PREFERENCES_D55;5500K PREFERENCES_D60;6000K PREFERENCES_D65;6500K -PREFERENCES_DARKFRAME;Темновой кадр PREFERENCES_DARKFRAMEFOUND;Найдено PREFERENCES_DARKFRAMESHOTS;снимков PREFERENCES_DARKFRAMETEMPLATES;шаблонов @@ -663,7 +662,6 @@ PREFERENCES_EXTERNALEDITOR;Внешний редактор PREFERENCES_FBROWSEROPTS;Настройки PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Однорядная панель обозревателя файлов (отключите для экранов с низким разрешением) PREFERENCES_FILEFORMAT;Формат файлов -PREFERENCES_FLATFIELD;Плоское поле PREFERENCES_FLATFIELDFOUND;Найдено PREFERENCES_FLATFIELDSDIR;Папка с файлами плоских полей PREFERENCES_FLATFIELDSHOTS;снимков @@ -1284,6 +1282,7 @@ ZOOMPANEL_ZOOMOUT;Удалить - !DYNPROFILEEDITOR_PROFILE;Processing Profile !EDIT_OBJECT_TOOLTIP;Displays a widget on the preview window which lets you adjust this tool. !EDIT_PIPETTE_TOOLTIP;To add an adjustment point to the curve, hold the Ctrl key while left-clicking the desired spot in the image preview.\nTo adjust the point, hold the Ctrl key while left-clicking the corresponding area in the preview, then let go of Ctrl (unless you desire fine control) and while still holding the left mouse button move the mouse up or down to move that point up or down in the curve. +!EXIFPANEL_SHOWALL;Show all !EXPORT_BYPASS;Processing steps to bypass !EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels !EXPORT_PIPELINE;Processing pipeline @@ -1523,6 +1522,12 @@ ZOOMPANEL_ZOOMOUT;Удалить - !HISTORY_MSG_482;CAM02 - Green scene !HISTORY_MSG_483;CAM02 - Yb scene !HISTORY_MSG_484;CAM02 - Auto Yb scene +!HISTORY_MSG_485;Lens Correction +!HISTORY_MSG_486;Lens Correction - Camera +!HISTORY_MSG_487;Lens Correction - Lens +!HISTORY_MSG_488;HDR Tone Mapping +!HISTORY_MSG_489;HDR TM - Threshold +!HISTORY_MSG_490;HDR TM - Amount !IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider. !IPTCPANEL_CITYHINT;Enter the name of the city pictured in this image. !IPTCPANEL_COPYRIGHT;Copyright notice @@ -1548,11 +1553,16 @@ ZOOMPANEL_ZOOMOUT;Удалить - !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. +!LENSPROFILE_CORRECTION_AUTOMATCH;Auto-matched correction parameters +!LENSPROFILE_CORRECTION_LCPFILE;LCP File +!LENSPROFILE_CORRECTION_MANUAL;Manual correction parameters +!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. !MAIN_BUTTON_SENDTOEDITOR;Edit image in external editor !MAIN_MSG_TOOMANYOPENEDITORS;Too many open editors.\nPlease close an editor to continue. !MAIN_TAB_INSPECT; Inspect !MAIN_TAB_WAVELET;Wavelet !MAIN_TAB_WAVELET_TOOLTIP;Shortcut: Alt-w +!MAIN_TOOLTIP_BACKCOLOR3;Background color of the preview: Middle grey\nShortcut: 9 !MAIN_TOOLTIP_HIDEHP;Show/Hide the left panel (including the history).\nShortcut: l !MONITOR_PROFILE_SYSTEM;System default !NAVIGATOR_B;B: @@ -1574,14 +1584,16 @@ ZOOMPANEL_ZOOMOUT;Удалить - !PARTIALPASTE_PRSHARPENING;Post-resize sharpening !PARTIALPASTE_RAWCACORR_CAREDBLUE;CA red & blue !PARTIALPASTE_RAW_IMAGENUM;Sub-image -!PARTIALPASTE_RAW_PIXELSHIFT;PixelShift +!PARTIALPASTE_RAW_PIXELSHIFT;Pixel Shift !PARTIALPASTE_RETINEX;Retinex +!PARTIALPASTE_TM_FATTAL;HDR Tone mapping !PARTIALPASTE_WAVELETGROUP;Wavelet Levels !PREFERENCES_AUTLISLOW;Low !PREFERENCES_AUTLISMAX;Max - Average of all tiles !PREFERENCES_AUTLISSTD;High !PREFERENCES_AUTLISVLOW;None !PREFERENCES_AUTLOW;Low +!PREFERENCES_AUTOSAVE_TP_OPEN;Automatically save tools collapsed/expanded\nstate before exiting !PREFERENCES_AUTSTD;Standard !PREFERENCES_CIEART_FRAME;CIECAM02-Specific Settings !PREFERENCES_CLUTSCACHE;HaldCLUT Cache @@ -1596,8 +1608,8 @@ ZOOMPANEL_ZOOMOUT;Удалить - !PREFERENCES_D50_OLD;5000K !PREFERENCES_DAUB_LABEL;Use Daubechies D6 wavelets instead of D4 !PREFERENCES_DAUB_TOOLTIP;The Noise Reduction and Wavelet Levels tools use a Debauchies mother wavelet. If you choose D6 instead of D4 you increase the number of orthogonal Daubechies coefficients and probably increase quality of small-scale levels. There is no memory or processing time difference between the two. +!PREFERENCES_DIRECTORIES;Directories !PREFERENCES_EXPAUT;Expert -!PREFERENCES_FILMSIMULATION;Film Simulation !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_GREY18_OLD;Yb=18 CIE L#50 @@ -1640,6 +1652,7 @@ ZOOMPANEL_ZOOMOUT;Удалить - !PREFERENCES_PRTPROFILE;Color profile !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 tools collapsed/expanded state now !PREFERENCES_SELECTFONT_COLPICKER;Select Color Picker's font !PREFERENCES_SERIALIZE_TIFF_READ;Tiff Read Settings !PREFERENCES_SERIALIZE_TIFF_READ_LABEL;Serialize read of tiff files @@ -1659,9 +1672,18 @@ ZOOMPANEL_ZOOMOUT;Удалить - !PREFERENCES_WLTWO;Two levels !PREFERENCES_WLZER;No !PROFILEPANEL_PDYNAMIC;Dynamic +!QINFO_FRAMECOUNT;%2 frames +!QINFO_HDR;HDR / %2 frame(s) +!QINFO_PIXELSHIFT;Pixel Shift / %2 frame(s) +!SAMPLEFORMAT_0;Unknown data format +!SAMPLEFORMAT_1;Unsigned 8 bits +!SAMPLEFORMAT_2;Unsigned 16 bits +!SAMPLEFORMAT_4;LogLuv 24 bits +!SAMPLEFORMAT_8;LogLuv 32 bits +!SAMPLEFORMAT_16;32 bits 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;If active, indicates in grey the pixels which have out of gamut colors from the output profile. -!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate de rendering generated by the output profile of the ICM tool. Most useful for simulating printing outputs. +!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the Printer profile. +!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate the printer's output by using the Printer profile set in Preferences > Color Management. !TOOLBAR_TOOLTIP_COLORPICKER;Lockable Color Picker\n\nWhen enabled:\nClick in the preview with left mouse button to add a color picker\nDrag it around while pressing the left mouse button\nDelete the color picker with a right mouse button click\nDelete all color pickers with Shift + Right mouse button click\nRight click away from any color picker to go back to the Hand tool !TP_BWMIX_SET_RGBABS;Absolute RGB !TP_BWMIX_SET_RGBREL;Relative RGB @@ -1703,7 +1725,7 @@ ZOOMPANEL_ZOOMOUT;Удалить - !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 Tint=1.\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\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504 !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_WBCAM;WB [RT+CAT02] + [output] @@ -1992,6 +2014,9 @@ ZOOMPANEL_ZOOMOUT;Удалить - !TP_RETINEX_VIEW_TRAN;Transmission - Auto !TP_RETINEX_VIEW_TRAN2;Transmission - Fixed !TP_RETINEX_VIEW_UNSHARP;Unsharp mask +!TP_TM_FATTAL_AMOUNT;Amount +!TP_TM_FATTAL_LABEL;HDR Tone Mapping +!TP_TM_FATTAL_THRESHOLD;Threshold !TP_WAVELET_1;Level 1 !TP_WAVELET_2;Level 2 !TP_WAVELET_3;Level 3 diff --git a/rtdata/languages/Serbian (Cyrilic Characters) b/rtdata/languages/Serbian (Cyrilic Characters) index 2a9e96bc0..b6f614cce 100644 --- a/rtdata/languages/Serbian (Cyrilic Characters) +++ b/rtdata/languages/Serbian (Cyrilic Characters) @@ -631,7 +631,6 @@ PREFERENCES_D50;5000K PREFERENCES_D55;5500K PREFERENCES_D60;6000K PREFERENCES_D65;6500K -PREFERENCES_DARKFRAME;Тамни кадар PREFERENCES_DARKFRAMEFOUND;Нађен PREFERENCES_DARKFRAMESHOTS;снимака PREFERENCES_DARKFRAMETEMPLATES;шаблони @@ -649,7 +648,6 @@ PREFERENCES_EXTERNALEDITOR;Спољни уређивач PREFERENCES_FBROWSEROPTS;Опције разгледача датотеке PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Прикажи алатке у једном реду PREFERENCES_FILEFORMAT;Формат датотеке -PREFERENCES_FLATFIELD;Равно поље PREFERENCES_FLATFIELDFOUND;Нађено PREFERENCES_FLATFIELDSDIR;Директоријум за равна поља PREFERENCES_FLATFIELDSHOTS;снимака @@ -1306,6 +1304,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !DYNPROFILEEDITOR_PROFILE;Processing Profile !EDIT_OBJECT_TOOLTIP;Displays a widget on the preview window which lets you adjust this tool. !EDIT_PIPETTE_TOOLTIP;To add an adjustment point to the curve, hold the Ctrl key while left-clicking the desired spot in the image preview.\nTo adjust the point, hold the Ctrl key while left-clicking the corresponding area in the preview, then let go of Ctrl (unless you desire fine control) and while still holding the left mouse button move the mouse up or down to move that point up or down in the curve. +!EXIFPANEL_SHOWALL;Show all !EXPORT_BYPASS;Processing steps to bypass !EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels !EXPORT_PIPELINE;Processing pipeline @@ -1556,6 +1555,12 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !HISTORY_MSG_482;CAM02 - Green scene !HISTORY_MSG_483;CAM02 - Yb scene !HISTORY_MSG_484;CAM02 - Auto Yb scene +!HISTORY_MSG_485;Lens Correction +!HISTORY_MSG_486;Lens Correction - Camera +!HISTORY_MSG_487;Lens Correction - Lens +!HISTORY_MSG_488;HDR Tone Mapping +!HISTORY_MSG_489;HDR TM - Threshold +!HISTORY_MSG_490;HDR TM - Amount !IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider. !IPTCPANEL_CITYHINT;Enter the name of the city pictured in this image. !IPTCPANEL_COPYRIGHT;Copyright notice @@ -1581,10 +1586,15 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !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. +!LENSPROFILE_CORRECTION_AUTOMATCH;Auto-matched correction parameters +!LENSPROFILE_CORRECTION_LCPFILE;LCP File +!LENSPROFILE_CORRECTION_MANUAL;Manual correction parameters +!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. !MAIN_MSG_TOOMANYOPENEDITORS;Too many open editors.\nPlease close an editor to continue. !MAIN_TAB_INSPECT; Inspect !MAIN_TAB_WAVELET;Wavelet !MAIN_TAB_WAVELET_TOOLTIP;Shortcut: Alt-w +!MAIN_TOOLTIP_BACKCOLOR3;Background color of the preview: Middle grey\nShortcut: 9 !MONITOR_PROFILE_SYSTEM;System default !NAVIGATOR_B;B: !NAVIGATOR_G;G: @@ -1606,14 +1616,16 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !PARTIALPASTE_PRSHARPENING;Post-resize sharpening !PARTIALPASTE_RAWCACORR_CAREDBLUE;CA red & blue !PARTIALPASTE_RAW_IMAGENUM;Sub-image -!PARTIALPASTE_RAW_PIXELSHIFT;PixelShift +!PARTIALPASTE_RAW_PIXELSHIFT;Pixel Shift !PARTIALPASTE_RETINEX;Retinex +!PARTIALPASTE_TM_FATTAL;HDR Tone mapping !PARTIALPASTE_WAVELETGROUP;Wavelet Levels !PREFERENCES_AUTLISLOW;Low !PREFERENCES_AUTLISMAX;Max - Average of all tiles !PREFERENCES_AUTLISSTD;High !PREFERENCES_AUTLISVLOW;None !PREFERENCES_AUTLOW;Low +!PREFERENCES_AUTOSAVE_TP_OPEN;Automatically save tools collapsed/expanded\nstate before exiting !PREFERENCES_AUTSTD;Standard !PREFERENCES_CIEART_FRAME;CIECAM02-Specific Settings !PREFERENCES_CLUTSCACHE;HaldCLUT Cache @@ -1628,8 +1640,8 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !PREFERENCES_D50_OLD;5000K !PREFERENCES_DAUB_LABEL;Use Daubechies D6 wavelets instead of D4 !PREFERENCES_DAUB_TOOLTIP;The Noise Reduction and Wavelet Levels tools use a Debauchies mother wavelet. If you choose D6 instead of D4 you increase the number of orthogonal Daubechies coefficients and probably increase quality of small-scale levels. There is no memory or processing time difference between the two. +!PREFERENCES_DIRECTORIES;Directories !PREFERENCES_EXPAUT;Expert -!PREFERENCES_FILMSIMULATION;Film Simulation !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_GREY18_OLD;Yb=18 CIE L#50 @@ -1672,6 +1684,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !PREFERENCES_PRTPROFILE;Color profile !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 tools collapsed/expanded state now !PREFERENCES_SELECTFONT_COLPICKER;Select Color Picker's font !PREFERENCES_SERIALIZE_TIFF_READ;Tiff Read Settings !PREFERENCES_SERIALIZE_TIFF_READ_LABEL;Serialize read of tiff files @@ -1690,8 +1703,17 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !PREFERENCES_WLTWO;Two levels !PREFERENCES_WLZER;No !PROFILEPANEL_PDYNAMIC;Dynamic -!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the output profile. -!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate de rendering generated by the output profile of the ICM tool. Most useful for simulating printing outputs. +!QINFO_FRAMECOUNT;%2 frames +!QINFO_HDR;HDR / %2 frame(s) +!QINFO_PIXELSHIFT;Pixel Shift / %2 frame(s) +!SAMPLEFORMAT_0;Unknown data format +!SAMPLEFORMAT_1;Unsigned 8 bits +!SAMPLEFORMAT_2;Unsigned 16 bits +!SAMPLEFORMAT_4;LogLuv 24 bits +!SAMPLEFORMAT_8;LogLuv 32 bits +!SAMPLEFORMAT_16;32 bits floating point +!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the Printer profile. +!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate the printer's output by using the Printer profile set in Preferences > Color Management. !THRESHOLDSELECTOR_BL;Bottom-left !TOOLBAR_TOOLTIP_COLORPICKER;Lockable Color Picker\n\nWhen enabled:\nClick in the preview with left mouse button to add a color picker\nDrag it around while pressing the left mouse button\nDelete the color picker with a right mouse button click\nDelete all color pickers with Shift + Right mouse button click\nRight click away from any color picker to go back to the Hand tool !TP_BWMIX_FILTER_TOOLTIP;The color filter simulates shots taken with a colored filter placed in front of the lens. Colored filters reduce the transmission of specific color ranges and therefore affect their lightness. E.g. a red filter darkens blue skies. @@ -1705,7 +1727,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !TP_COLORAPP_FREE;Free temp+green + CAT02 + [output] !TP_COLORAPP_NEUTRAL;Reset !TP_COLORAPP_NEUTRAL_TIP;Reset all sliders checkbox and curves to their default values -!TP_COLORAPP_TEMP_TOOLTIP;To select an illuminant always Tint=1.\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\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504 !TP_COLORAPP_YB;Yb% (mean luminance) !TP_COLORAPP_YBSCENE;Yb% (mean luminance) !TP_COLORAPP_YBSCENE_TOOLTIP;if auto enable, Yb is calculated from the mean value of actual image luminance @@ -1991,6 +2013,9 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !TP_RETINEX_VIEW_TRAN;Transmission - Auto !TP_RETINEX_VIEW_TRAN2;Transmission - Fixed !TP_RETINEX_VIEW_UNSHARP;Unsharp mask +!TP_TM_FATTAL_AMOUNT;Amount +!TP_TM_FATTAL_LABEL;HDR Tone Mapping +!TP_TM_FATTAL_THRESHOLD;Threshold !TP_WAVELET_1;Level 1 !TP_WAVELET_2;Level 2 !TP_WAVELET_3;Level 3 diff --git a/rtdata/languages/Serbian (Latin Characters) b/rtdata/languages/Serbian (Latin Characters) index 333c71203..6feba1bf3 100644 --- a/rtdata/languages/Serbian (Latin Characters) +++ b/rtdata/languages/Serbian (Latin Characters) @@ -631,7 +631,6 @@ PREFERENCES_D50;5000K PREFERENCES_D55;5500K PREFERENCES_D60;6000K PREFERENCES_D65;6500K -PREFERENCES_DARKFRAME;Tamni kadar PREFERENCES_DARKFRAMEFOUND;Nađen PREFERENCES_DARKFRAMESHOTS;snimaka PREFERENCES_DARKFRAMETEMPLATES;šabloni @@ -649,7 +648,6 @@ PREFERENCES_EXTERNALEDITOR;Spoljni uređivač PREFERENCES_FBROWSEROPTS;Opcije razgledača datoteke PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Prikaži alatke u jednom redu PREFERENCES_FILEFORMAT;Format datoteke -PREFERENCES_FLATFIELD;Ravno polje PREFERENCES_FLATFIELDFOUND;Nađeno PREFERENCES_FLATFIELDSDIR;Direktorijum za ravna polja PREFERENCES_FLATFIELDSHOTS;snimaka @@ -1306,6 +1304,7 @@ ZOOMPANEL_ZOOMOUT;Umanjuje prikaz slike - !DYNPROFILEEDITOR_PROFILE;Processing Profile !EDIT_OBJECT_TOOLTIP;Displays a widget on the preview window which lets you adjust this tool. !EDIT_PIPETTE_TOOLTIP;To add an adjustment point to the curve, hold the Ctrl key while left-clicking the desired spot in the image preview.\nTo adjust the point, hold the Ctrl key while left-clicking the corresponding area in the preview, then let go of Ctrl (unless you desire fine control) and while still holding the left mouse button move the mouse up or down to move that point up or down in the curve. +!EXIFPANEL_SHOWALL;Show all !EXPORT_BYPASS;Processing steps to bypass !EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels !EXPORT_PIPELINE;Processing pipeline @@ -1556,6 +1555,12 @@ ZOOMPANEL_ZOOMOUT;Umanjuje prikaz slike - !HISTORY_MSG_482;CAM02 - Green scene !HISTORY_MSG_483;CAM02 - Yb scene !HISTORY_MSG_484;CAM02 - Auto Yb scene +!HISTORY_MSG_485;Lens Correction +!HISTORY_MSG_486;Lens Correction - Camera +!HISTORY_MSG_487;Lens Correction - Lens +!HISTORY_MSG_488;HDR Tone Mapping +!HISTORY_MSG_489;HDR TM - Threshold +!HISTORY_MSG_490;HDR TM - Amount !IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider. !IPTCPANEL_CITYHINT;Enter the name of the city pictured in this image. !IPTCPANEL_COPYRIGHT;Copyright notice @@ -1581,10 +1586,15 @@ ZOOMPANEL_ZOOMOUT;Umanjuje prikaz slike - !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. +!LENSPROFILE_CORRECTION_AUTOMATCH;Auto-matched correction parameters +!LENSPROFILE_CORRECTION_LCPFILE;LCP File +!LENSPROFILE_CORRECTION_MANUAL;Manual correction parameters +!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. !MAIN_MSG_TOOMANYOPENEDITORS;Too many open editors.\nPlease close an editor to continue. !MAIN_TAB_INSPECT; Inspect !MAIN_TAB_WAVELET;Wavelet !MAIN_TAB_WAVELET_TOOLTIP;Shortcut: Alt-w +!MAIN_TOOLTIP_BACKCOLOR3;Background color of the preview: Middle grey\nShortcut: 9 !MONITOR_PROFILE_SYSTEM;System default !NAVIGATOR_B;B: !NAVIGATOR_G;G: @@ -1606,14 +1616,16 @@ ZOOMPANEL_ZOOMOUT;Umanjuje prikaz slike - !PARTIALPASTE_PRSHARPENING;Post-resize sharpening !PARTIALPASTE_RAWCACORR_CAREDBLUE;CA red & blue !PARTIALPASTE_RAW_IMAGENUM;Sub-image -!PARTIALPASTE_RAW_PIXELSHIFT;PixelShift +!PARTIALPASTE_RAW_PIXELSHIFT;Pixel Shift !PARTIALPASTE_RETINEX;Retinex +!PARTIALPASTE_TM_FATTAL;HDR Tone mapping !PARTIALPASTE_WAVELETGROUP;Wavelet Levels !PREFERENCES_AUTLISLOW;Low !PREFERENCES_AUTLISMAX;Max - Average of all tiles !PREFERENCES_AUTLISSTD;High !PREFERENCES_AUTLISVLOW;None !PREFERENCES_AUTLOW;Low +!PREFERENCES_AUTOSAVE_TP_OPEN;Automatically save tools collapsed/expanded\nstate before exiting !PREFERENCES_AUTSTD;Standard !PREFERENCES_CIEART_FRAME;CIECAM02-Specific Settings !PREFERENCES_CLUTSCACHE;HaldCLUT Cache @@ -1628,8 +1640,8 @@ ZOOMPANEL_ZOOMOUT;Umanjuje prikaz slike - !PREFERENCES_D50_OLD;5000K !PREFERENCES_DAUB_LABEL;Use Daubechies D6 wavelets instead of D4 !PREFERENCES_DAUB_TOOLTIP;The Noise Reduction and Wavelet Levels tools use a Debauchies mother wavelet. If you choose D6 instead of D4 you increase the number of orthogonal Daubechies coefficients and probably increase quality of small-scale levels. There is no memory or processing time difference between the two. +!PREFERENCES_DIRECTORIES;Directories !PREFERENCES_EXPAUT;Expert -!PREFERENCES_FILMSIMULATION;Film Simulation !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_GREY18_OLD;Yb=18 CIE L#50 @@ -1672,6 +1684,7 @@ ZOOMPANEL_ZOOMOUT;Umanjuje prikaz slike - !PREFERENCES_PRTPROFILE;Color profile !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 tools collapsed/expanded state now !PREFERENCES_SELECTFONT_COLPICKER;Select Color Picker's font !PREFERENCES_SERIALIZE_TIFF_READ;Tiff Read Settings !PREFERENCES_SERIALIZE_TIFF_READ_LABEL;Serialize read of tiff files @@ -1690,8 +1703,17 @@ ZOOMPANEL_ZOOMOUT;Umanjuje prikaz slike - !PREFERENCES_WLTWO;Two levels !PREFERENCES_WLZER;No !PROFILEPANEL_PDYNAMIC;Dynamic -!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the output profile. -!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate de rendering generated by the output profile of the ICM tool. Most useful for simulating printing outputs. +!QINFO_FRAMECOUNT;%2 frames +!QINFO_HDR;HDR / %2 frame(s) +!QINFO_PIXELSHIFT;Pixel Shift / %2 frame(s) +!SAMPLEFORMAT_0;Unknown data format +!SAMPLEFORMAT_1;Unsigned 8 bits +!SAMPLEFORMAT_2;Unsigned 16 bits +!SAMPLEFORMAT_4;LogLuv 24 bits +!SAMPLEFORMAT_8;LogLuv 32 bits +!SAMPLEFORMAT_16;32 bits floating point +!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the Printer profile. +!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate the printer's output by using the Printer profile set in Preferences > Color Management. !THRESHOLDSELECTOR_BL;Bottom-left !TOOLBAR_TOOLTIP_COLORPICKER;Lockable Color Picker\n\nWhen enabled:\nClick in the preview with left mouse button to add a color picker\nDrag it around while pressing the left mouse button\nDelete the color picker with a right mouse button click\nDelete all color pickers with Shift + Right mouse button click\nRight click away from any color picker to go back to the Hand tool !TP_BWMIX_FILTER_TOOLTIP;The color filter simulates shots taken with a colored filter placed in front of the lens. Colored filters reduce the transmission of specific color ranges and therefore affect their lightness. E.g. a red filter darkens blue skies. @@ -1705,7 +1727,7 @@ ZOOMPANEL_ZOOMOUT;Umanjuje prikaz slike - !TP_COLORAPP_FREE;Free temp+green + CAT02 + [output] !TP_COLORAPP_NEUTRAL;Reset !TP_COLORAPP_NEUTRAL_TIP;Reset all sliders checkbox and curves to their default values -!TP_COLORAPP_TEMP_TOOLTIP;To select an illuminant always Tint=1.\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\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504 !TP_COLORAPP_YB;Yb% (mean luminance) !TP_COLORAPP_YBSCENE;Yb% (mean luminance) !TP_COLORAPP_YBSCENE_TOOLTIP;if auto enable, Yb is calculated from the mean value of actual image luminance @@ -1991,6 +2013,9 @@ ZOOMPANEL_ZOOMOUT;Umanjuje prikaz slike - !TP_RETINEX_VIEW_TRAN;Transmission - Auto !TP_RETINEX_VIEW_TRAN2;Transmission - Fixed !TP_RETINEX_VIEW_UNSHARP;Unsharp mask +!TP_TM_FATTAL_AMOUNT;Amount +!TP_TM_FATTAL_LABEL;HDR Tone Mapping +!TP_TM_FATTAL_THRESHOLD;Threshold !TP_WAVELET_1;Level 1 !TP_WAVELET_2;Level 2 !TP_WAVELET_3;Level 3 diff --git a/rtdata/languages/Slovak b/rtdata/languages/Slovak index f2bb37943..f589c3ee1 100644 --- a/rtdata/languages/Slovak +++ b/rtdata/languages/Slovak @@ -543,6 +543,7 @@ ZOOMPANEL_ZOOMOUT;Oddialiť - !EDIT_PIPETTE_TOOLTIP;To add an adjustment point to the curve, hold the Ctrl key while left-clicking the desired spot in the image preview.\nTo adjust the point, hold the Ctrl key while left-clicking the corresponding area in the preview, then let go of Ctrl (unless you desire fine control) and while still holding the left mouse button move the mouse up or down to move that point up or down in the curve. !EXIFFILTER_EXPOSURECOMPENSATION;Exposure compensation (EV) !EXIFFILTER_FILETYPE;File type +!EXIFPANEL_SHOWALL;Show all !EXPORT_BYPASS;Processing steps to bypass !EXPORT_BYPASS_ALL;Select / Unselect All !EXPORT_BYPASS_DEFRINGE;Bypass Defringe @@ -1030,6 +1031,12 @@ ZOOMPANEL_ZOOMOUT;Oddialiť - !HISTORY_MSG_482;CAM02 - Green scene !HISTORY_MSG_483;CAM02 - Yb scene !HISTORY_MSG_484;CAM02 - Auto Yb scene +!HISTORY_MSG_485;Lens Correction +!HISTORY_MSG_486;Lens Correction - Camera +!HISTORY_MSG_487;Lens Correction - Lens +!HISTORY_MSG_488;HDR Tone Mapping +!HISTORY_MSG_489;HDR TM - Threshold +!HISTORY_MSG_490;HDR TM - Amount !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider. !IPTCPANEL_CITYHINT;Enter the name of the city pictured in this image. @@ -1056,6 +1063,10 @@ ZOOMPANEL_ZOOMOUT;Oddialiť - !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. +!LENSPROFILE_CORRECTION_AUTOMATCH;Auto-matched correction parameters +!LENSPROFILE_CORRECTION_LCPFILE;LCP File +!LENSPROFILE_CORRECTION_MANUAL;Manual correction parameters +!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. !MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the next image relative to image opened in the Editor.\nShortcut: Shift-F4\n\nTo navigate to the next image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F4 !MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the previous image relative to image opened in the Editor.\nShortcut: Shift-F3\n\nTo navigate to the previous image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F3 !MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchronize the File Browser or Filmstrip with the Editor to reveal the thumbnail of the currently opened image, and clear any active filters.\nShortcut: x\n\nAs above, but without clearing active filters:\nShortcut: y\n(Note that the thumbnail of the opened image will not be shown if filtered out). @@ -1085,6 +1096,7 @@ ZOOMPANEL_ZOOMOUT;Oddialiť - !MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 9 !MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 !MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 9 +!MAIN_TOOLTIP_BACKCOLOR3;Background color of the preview: Middle grey\nShortcut: 9 !MAIN_TOOLTIP_BEFOREAFTERLOCK;Lock / Unlock the Before view\n\nLock: keep the Before view unchanged.\nUseful to evaluate the cumulative effect of multiple tools.\nAdditionally, comparisons can be made to any state in the History.\n\nUnlock: the Before view will follow the After view one step behind, showing the image before the effect of the currently used tool. !MAIN_TOOLTIP_PREVIEWB;Preview the Blue channel.\nShortcut: b !MAIN_TOOLTIP_PREVIEWFOCUSMASK;Preview the Focus Mask.\nShortcut: Shift-f\n\nMore accurate on images with shallow depth of field, low noise and at higher zoom levels.\n\nTo improve detection accuracy for noisy images evaluate at smaller zoom, about 10-30%. @@ -1132,7 +1144,7 @@ ZOOMPANEL_ZOOMOUT;Oddialiť - !PARTIALPASTE_GRADIENT;Graduated filter !PARTIALPASTE_HSVEQUALIZER;HSV equalizer !PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction -!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_LENSPROFILE;Profiled lens correction !PARTIALPASTE_PCVIGNETTE;Vignette filter !PARTIALPASTE_PERSPECTIVE;Perspective !PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter @@ -1152,11 +1164,12 @@ ZOOMPANEL_ZOOMOUT;Oddialiť - !PARTIALPASTE_RAW_FALSECOLOR;False color suppression !PARTIALPASTE_RAW_IMAGENUM;Sub-image !PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps -!PARTIALPASTE_RAW_PIXELSHIFT;PixelShift +!PARTIALPASTE_RAW_PIXELSHIFT;Pixel Shift !PARTIALPASTE_RETINEX;Retinex !PARTIALPASTE_RGBCURVES;RGB curves !PARTIALPASTE_SHARPENEDGE;Edges !PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_TM_FATTAL;HDR Tone mapping !PARTIALPASTE_VIBRANCE;Vibrance !PARTIALPASTE_WAVELETGROUP;Wavelet Levels !PREFERENCES_AUTLISLOW;Low @@ -1165,6 +1178,7 @@ ZOOMPANEL_ZOOMOUT;Oddialiť - !PREFERENCES_AUTLISVLOW;None !PREFERENCES_AUTLOW;Low !PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +!PREFERENCES_AUTOSAVE_TP_OPEN;Automatically save tools collapsed/expanded\nstate before exiting !PREFERENCES_AUTSTD;Standard !PREFERENCES_BEHADDALL;All to 'Add' !PREFERENCES_BEHADDALLHINT;Set all parameters to the Add mode.\nAdjustments of parameters in the batch tool panel will be deltas to the stored values. @@ -1196,17 +1210,15 @@ ZOOMPANEL_ZOOMOUT;Oddialiť - !PREFERENCES_D55;5500K !PREFERENCES_D60;6000K !PREFERENCES_D65;6500K -!PREFERENCES_DARKFRAME;Dark-Frame !PREFERENCES_DARKFRAMEFOUND;Found !PREFERENCES_DARKFRAMESHOTS;shots !PREFERENCES_DARKFRAMETEMPLATES;templates !PREFERENCES_DAUB_LABEL;Use Daubechies D6 wavelets instead of D4 !PREFERENCES_DAUB_TOOLTIP;The Noise Reduction and Wavelet Levels tools use a Debauchies mother wavelet. If you choose D6 instead of D4 you increase the number of orthogonal Daubechies coefficients and probably increase quality of small-scale levels. There is no memory or processing time difference between the two. !PREFERENCES_DIRDARKFRAMES;Dark-frames directory +!PREFERENCES_DIRECTORIES;Directories !PREFERENCES_EXPAUT;Expert !PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar\n(de-select for low resolution display) -!PREFERENCES_FILMSIMULATION;Film Simulation -!PREFERENCES_FLATFIELD;Flat-Field !PREFERENCES_FLATFIELDFOUND;Found !PREFERENCES_FLATFIELDSDIR;Flat-fields directory !PREFERENCES_FLATFIELDSHOTS;shots @@ -1279,6 +1291,7 @@ ZOOMPANEL_ZOOMOUT;Oddialiť - !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_RGBDTL_LABEL;Max number of threads for Noise Reduction and Wavelet Levels !PREFERENCES_RGBDTL_TOOLTIP;Leave the setting at "0" to automatically use as many threads as possible. The more threads run in parallel, the faster the computation. Refer to RawPedia for memory requirements. +!PREFERENCES_SAVE_TP_OPEN_NOW;Save tools collapsed/expanded state now !PREFERENCES_SELECTFONT_COLPICKER;Select Color Picker's font !PREFERENCES_SERIALIZE_TIFF_READ;Tiff Read Settings !PREFERENCES_SERIALIZE_TIFF_READ_LABEL;Serialize read of tiff files @@ -1323,6 +1336,15 @@ ZOOMPANEL_ZOOMOUT;Oddialiť - !PROGRESSBAR_NOIMAGES;No images found !PROGRESSBAR_PROCESSING_PROFILESAVED;Processing profile saved !PROGRESSBAR_SNAPSHOT_ADDED;Snapshot added +!QINFO_FRAMECOUNT;%2 frames +!QINFO_HDR;HDR / %2 frame(s) +!QINFO_PIXELSHIFT;Pixel Shift / %2 frame(s) +!SAMPLEFORMAT_0;Unknown data format +!SAMPLEFORMAT_1;Unsigned 8 bits +!SAMPLEFORMAT_2;Unsigned 16 bits +!SAMPLEFORMAT_4;LogLuv 24 bits +!SAMPLEFORMAT_8;LogLuv 32 bits +!SAMPLEFORMAT_16;32 bits floating point !SAVEDLG_FORCEFORMATOPTS;Force saving options !SAVEDLG_SUBSAMP;Subsampling !SAVEDLG_SUBSAMP_1;Best compression @@ -1331,8 +1353,8 @@ ZOOMPANEL_ZOOMOUT;Oddialiť - !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. !SAVEDLG_WARNFILENAME;File will be named !SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. -!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the output profile. -!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate de rendering generated by the output profile of the ICM tool. Most useful for simulating printing outputs. +!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the Printer profile. +!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate the printer's output by using the Printer profile set in Preferences > Color Management. !THRESHOLDSELECTOR_B;Bottom !THRESHOLDSELECTOR_BL;Bottom-left !THRESHOLDSELECTOR_BR;Bottom-right @@ -1477,7 +1499,7 @@ ZOOMPANEL_ZOOMOUT;Oddialiť - !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 Tint=1.\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\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504 !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_WBCAM;WB [RT+CAT02] + [output] @@ -1721,7 +1743,7 @@ ZOOMPANEL_ZOOMOUT;Oddialiť - !TP_LABCURVE_LCREDSK_TIP;If enabled, the LC Curve affects only red and skin-tones.\nIf disabled, it applies to all tones. !TP_LABCURVE_RSTPROTECTION;Red and skin-tones protection !TP_LABCURVE_RSTPRO_TOOLTIP;Works on the Chromaticity slider and the CC curve. -!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_LABEL;Profiled Lens Correction !TP_LENSPROFILE_USECA;Chromatic aberration correction !TP_LENSPROFILE_USEDIST;Distortion correction !TP_LENSPROFILE_USEVIGN;Vignetting correction @@ -1933,6 +1955,9 @@ ZOOMPANEL_ZOOMOUT;Oddialiť - !TP_SHARPENMICRO_LABEL;Microcontrast !TP_SHARPENMICRO_MATRIX;3×3 matrix instead of 5×5 !TP_SHARPENMICRO_UNIFORMITY;Uniformity +!TP_TM_FATTAL_AMOUNT;Amount +!TP_TM_FATTAL_LABEL;HDR Tone Mapping +!TP_TM_FATTAL_THRESHOLD;Threshold !TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift !TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH !TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones diff --git a/rtdata/languages/Suomi b/rtdata/languages/Suomi index 8bb8dddad..ecdcfff8a 100644 --- a/rtdata/languages/Suomi +++ b/rtdata/languages/Suomi @@ -464,6 +464,7 @@ TP_WBALANCE_TEMPERATURE;Lämpötila [K] !EXIFFILTER_EXPOSURECOMPENSATION;Exposure compensation (EV) !EXIFFILTER_FILETYPE;File type !EXIFFILTER_METADATAFILTER;Enable metadata filters +!EXIFPANEL_SHOWALL;Show all !EXPORT_BYPASS;Processing steps to bypass !EXPORT_BYPASS_ALL;Select / Unselect All !EXPORT_BYPASS_DEFRINGE;Bypass Defringe @@ -586,7 +587,7 @@ TP_WBALANCE_TEMPERATURE;Lämpötila [K] !HISTORY_MSG_82;Profile changed !HISTORY_MSG_83;S/H - Sharp mask !HISTORY_MSG_84;Perspective correction -!HISTORY_MSG_85;LCP +!HISTORY_MSG_85;Lens Correction - LCP file !HISTORY_MSG_86;RGB Curves - Luminosity mode !HISTORY_MSG_87;Impulse Noise Reduction !HISTORY_MSG_88;Impulse NR threshold @@ -969,6 +970,12 @@ TP_WBALANCE_TEMPERATURE;Lämpötila [K] !HISTORY_MSG_482;CAM02 - Green scene !HISTORY_MSG_483;CAM02 - Yb scene !HISTORY_MSG_484;CAM02 - Auto Yb scene +!HISTORY_MSG_485;Lens Correction +!HISTORY_MSG_486;Lens Correction - Camera +!HISTORY_MSG_487;Lens Correction - Lens +!HISTORY_MSG_488;HDR Tone Mapping +!HISTORY_MSG_489;HDR TM - Threshold +!HISTORY_MSG_490;HDR TM - Amount !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider. !IPTCPANEL_CITYHINT;Enter the name of the city pictured in this image. @@ -995,6 +1002,10 @@ TP_WBALANCE_TEMPERATURE;Lämpötila [K] !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. +!LENSPROFILE_CORRECTION_AUTOMATCH;Auto-matched correction parameters +!LENSPROFILE_CORRECTION_LCPFILE;LCP File +!LENSPROFILE_CORRECTION_MANUAL;Manual correction parameters +!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. !MAIN_BUTTON_FULLSCREEN;Fullscreen !MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the next image relative to image opened in the Editor.\nShortcut: Shift-F4\n\nTo navigate to the next image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F4 !MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the previous image relative to image opened in the Editor.\nShortcut: Shift-F3\n\nTo navigate to the previous image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F3 @@ -1030,6 +1041,7 @@ TP_WBALANCE_TEMPERATURE;Lämpötila [K] !MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 9 !MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 !MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 9 +!MAIN_TOOLTIP_BACKCOLOR3;Background color of the preview: Middle grey\nShortcut: 9 !MAIN_TOOLTIP_BEFOREAFTERLOCK;Lock / Unlock the Before view\n\nLock: keep the Before view unchanged.\nUseful to evaluate the cumulative effect of multiple tools.\nAdditionally, comparisons can be made to any state in the History.\n\nUnlock: the Before view will follow the After view one step behind, showing the image before the effect of the currently used tool. !MAIN_TOOLTIP_PREVIEWB;Preview the Blue channel.\nShortcut: b !MAIN_TOOLTIP_PREVIEWFOCUSMASK;Preview the Focus Mask.\nShortcut: Shift-f\n\nMore accurate on images with shallow depth of field, low noise and at higher zoom levels.\n\nTo improve detection accuracy for noisy images evaluate at smaller zoom, about 10-30%. @@ -1080,7 +1092,7 @@ TP_WBALANCE_TEMPERATURE;Lämpötila [K] !PARTIALPASTE_HSVEQUALIZER;HSV equalizer !PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction !PARTIALPASTE_LABCURVE;L*a*b* adjustments -!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_LENSPROFILE;Profiled lens correction !PARTIALPASTE_PCVIGNETTE;Vignette filter !PARTIALPASTE_PERSPECTIVE;Perspective !PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter @@ -1100,11 +1112,12 @@ TP_WBALANCE_TEMPERATURE;Lämpötila [K] !PARTIALPASTE_RAW_FALSECOLOR;False color suppression !PARTIALPASTE_RAW_IMAGENUM;Sub-image !PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps -!PARTIALPASTE_RAW_PIXELSHIFT;PixelShift +!PARTIALPASTE_RAW_PIXELSHIFT;Pixel Shift !PARTIALPASTE_RETINEX;Retinex !PARTIALPASTE_RGBCURVES;RGB curves !PARTIALPASTE_SHARPENEDGE;Edges !PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_TM_FATTAL;HDR Tone mapping !PARTIALPASTE_VIBRANCE;Vibrance !PARTIALPASTE_WAVELETGROUP;Wavelet Levels !PREFERENCES_ADD;Add @@ -1114,6 +1127,7 @@ TP_WBALANCE_TEMPERATURE;Lämpötila [K] !PREFERENCES_AUTLISVLOW;None !PREFERENCES_AUTLOW;Low !PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +!PREFERENCES_AUTOSAVE_TP_OPEN;Automatically save tools collapsed/expanded\nstate before exiting !PREFERENCES_AUTSTD;Standard !PREFERENCES_BATCH_PROCESSING;Batch Processing !PREFERENCES_BEHADDALL;All to 'Add' @@ -1147,18 +1161,16 @@ TP_WBALANCE_TEMPERATURE;Lämpötila [K] !PREFERENCES_D55;5500K !PREFERENCES_D60;6000K !PREFERENCES_D65;6500K -!PREFERENCES_DARKFRAME;Dark-Frame !PREFERENCES_DARKFRAMEFOUND;Found !PREFERENCES_DARKFRAMESHOTS;shots !PREFERENCES_DARKFRAMETEMPLATES;templates !PREFERENCES_DAUB_LABEL;Use Daubechies D6 wavelets instead of D4 !PREFERENCES_DAUB_TOOLTIP;The Noise Reduction and Wavelet Levels tools use a Debauchies mother wavelet. If you choose D6 instead of D4 you increase the number of orthogonal Daubechies coefficients and probably increase quality of small-scale levels. There is no memory or processing time difference between the two. !PREFERENCES_DIRDARKFRAMES;Dark-frames directory +!PREFERENCES_DIRECTORIES;Directories !PREFERENCES_EDITORLAYOUT;Editor Layout !PREFERENCES_EXPAUT;Expert !PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar\n(de-select for low resolution display) -!PREFERENCES_FILMSIMULATION;Film Simulation -!PREFERENCES_FLATFIELD;Flat-Field !PREFERENCES_FLATFIELDFOUND;Found !PREFERENCES_FLATFIELDSDIR;Flat-fields directory !PREFERENCES_FLATFIELDSHOTS;shots @@ -1234,6 +1246,7 @@ TP_WBALANCE_TEMPERATURE;Lämpötila [K] !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_RGBDTL_LABEL;Max number of threads for Noise Reduction and Wavelet Levels !PREFERENCES_RGBDTL_TOOLTIP;Leave the setting at "0" to automatically use as many threads as possible. The more threads run in parallel, the faster the computation. Refer to RawPedia for memory requirements. +!PREFERENCES_SAVE_TP_OPEN_NOW;Save tools collapsed/expanded state now !PREFERENCES_SELECTFONT;Select main font !PREFERENCES_SELECTFONT_COLPICKER;Select Color Picker's font !PREFERENCES_SERIALIZE_TIFF_READ;Tiff Read Settings @@ -1283,6 +1296,15 @@ TP_WBALANCE_TEMPERATURE;Lämpötila [K] !PROGRESSBAR_PROCESSING_PROFILESAVED;Processing profile saved !PROGRESSBAR_SNAPSHOT_ADDED;Snapshot added !PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!QINFO_FRAMECOUNT;%2 frames +!QINFO_HDR;HDR / %2 frame(s) +!QINFO_PIXELSHIFT;Pixel Shift / %2 frame(s) +!SAMPLEFORMAT_0;Unknown data format +!SAMPLEFORMAT_1;Unsigned 8 bits +!SAMPLEFORMAT_2;Unsigned 16 bits +!SAMPLEFORMAT_4;LogLuv 24 bits +!SAMPLEFORMAT_8;LogLuv 32 bits +!SAMPLEFORMAT_16;32 bits floating point !SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists !SAVEDLG_FORCEFORMATOPTS;Force saving options !SAVEDLG_SUBSAMP;Subsampling @@ -1292,8 +1314,8 @@ TP_WBALANCE_TEMPERATURE;Lämpötila [K] !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. !SAVEDLG_WARNFILENAME;File will be named !SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. -!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the output profile. -!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate de rendering generated by the output profile of the ICM tool. Most useful for simulating printing outputs. +!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the Printer profile. +!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate the printer's output by using the Printer profile set in Preferences > Color Management. !THRESHOLDSELECTOR_B;Bottom !THRESHOLDSELECTOR_BL;Bottom-left !THRESHOLDSELECTOR_BR;Bottom-right @@ -1438,7 +1460,7 @@ TP_WBALANCE_TEMPERATURE;Lämpötila [K] !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 Tint=1.\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\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504 !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_WBCAM;WB [RT+CAT02] + [output] @@ -1702,7 +1724,7 @@ TP_WBALANCE_TEMPERATURE;Lämpötila [K] !TP_LENSGEOM_AUTOCROP;Auto-Crop !TP_LENSGEOM_FILL;Auto-fill !TP_LENSGEOM_LABEL;Lens / Geometry -!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_LABEL;Profiled Lens Correction !TP_LENSPROFILE_USECA;Chromatic aberration correction !TP_LENSPROFILE_USEDIST;Distortion correction !TP_LENSPROFILE_USEVIGN;Vignetting correction @@ -1925,6 +1947,9 @@ TP_WBALANCE_TEMPERATURE;Lämpötila [K] !TP_SHARPENMICRO_LABEL;Microcontrast !TP_SHARPENMICRO_MATRIX;3×3 matrix instead of 5×5 !TP_SHARPENMICRO_UNIFORMITY;Uniformity +!TP_TM_FATTAL_AMOUNT;Amount +!TP_TM_FATTAL_LABEL;HDR Tone Mapping +!TP_TM_FATTAL_THRESHOLD;Threshold !TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift !TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH !TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones diff --git a/rtdata/languages/Swedish b/rtdata/languages/Swedish index 0a75c54ea..0f3ddaafd 100644 --- a/rtdata/languages/Swedish +++ b/rtdata/languages/Swedish @@ -870,7 +870,6 @@ PREFERENCES_D50;5000K PREFERENCES_D55;5500K PREFERENCES_D60;6000K PREFERENCES_D65;6500K -PREFERENCES_DARKFRAME;Svartbild PREFERENCES_DARKFRAMEFOUND;Hittade PREFERENCES_DARKFRAMESHOTS;bilder PREFERENCES_DARKFRAMETEMPLATES;mallar @@ -891,8 +890,6 @@ PREFERENCES_EXTERNALEDITOR;Externt bildredigeringsprogram PREFERENCES_FBROWSEROPTS;Inställningar för filvyn/miniatyrbilderna PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Filvyns verktygsrad som en rad (avmarkera för lågupplösta skärmar) PREFERENCES_FILEFORMAT;Filformat -PREFERENCES_FILMSIMULATION;Filmsimulering -PREFERENCES_FLATFIELD;Plattfält PREFERENCES_FLATFIELDFOUND;Hittade PREFERENCES_FLATFIELDSDIR;Plattfältskatalog PREFERENCES_FLATFIELDSHOTS;bilder @@ -1896,6 +1893,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !DYNPROFILEEDITOR_NEW;New !DYNPROFILEEDITOR_NEW_RULE;New Dynamic Profile Rule !DYNPROFILEEDITOR_PROFILE;Processing Profile +!EXIFPANEL_SHOWALL;Show all !EXPORT_BYPASS;Processing steps to bypass !EXPORT_PIPELINE;Processing pipeline !EXPORT_USE_FAST_PIPELINE;Dedicated (full processing on resized image) @@ -1951,6 +1949,12 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !HISTORY_MSG_482;CAM02 - Green scene !HISTORY_MSG_483;CAM02 - Yb scene !HISTORY_MSG_484;CAM02 - Auto Yb scene +!HISTORY_MSG_485;Lens Correction +!HISTORY_MSG_486;Lens Correction - Camera +!HISTORY_MSG_487;Lens Correction - Lens +!HISTORY_MSG_488;HDR Tone Mapping +!HISTORY_MSG_489;HDR TM - Threshold +!HISTORY_MSG_490;HDR TM - Amount !IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider. !IPTCPANEL_CITYHINT;Enter the name of the city pictured in this image. !IPTCPANEL_COPYRIGHT;Copyright notice @@ -1976,14 +1980,22 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !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. +!LENSPROFILE_CORRECTION_AUTOMATCH;Auto-matched correction parameters +!LENSPROFILE_CORRECTION_LCPFILE;LCP File +!LENSPROFILE_CORRECTION_MANUAL;Manual correction parameters +!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. !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 !PARTIALPASTE_COLORTONING;Color toning !PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field clip control !PARTIALPASTE_RAWCACORR_CAREDBLUE;CA red & blue !PARTIALPASTE_RAW_IMAGENUM;Sub-image -!PARTIALPASTE_RAW_PIXELSHIFT;PixelShift +!PARTIALPASTE_RAW_PIXELSHIFT;Pixel Shift +!PARTIALPASTE_TM_FATTAL;HDR Tone mapping +!PREFERENCES_AUTOSAVE_TP_OPEN;Automatically save tools collapsed/expanded\nstate before exiting !PREFERENCES_CMMBPC;Black point compensation !PREFERENCES_D50_OLD;5000K +!PREFERENCES_DIRECTORIES;Directories !PREFERENCES_GREY18_OLD;Yb=18 CIE L#50 !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_LANG;Language @@ -1997,15 +2009,25 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !PREFERENCES_PROFILESAVELOCATION;Processing profile saving location !PREFERENCES_PRTINTENT;Rendering intent !PREFERENCES_PRTPROFILE;Color profile +!PREFERENCES_SAVE_TP_OPEN_NOW;Save tools collapsed/expanded state now !PREFERENCES_SERIALIZE_TIFF_READ;Tiff Read Settings !PREFERENCES_TAB_DYNAMICPROFILE;Dynamic Profile Rules !PREFERENCES_THEME;Theme !PROFILEPANEL_PDYNAMIC;Dynamic +!QINFO_FRAMECOUNT;%2 frames +!QINFO_HDR;HDR / %2 frame(s) +!QINFO_PIXELSHIFT;Pixel Shift / %2 frame(s) +!SAMPLEFORMAT_0;Unknown data format +!SAMPLEFORMAT_1;Unsigned 8 bits +!SAMPLEFORMAT_2;Unsigned 16 bits +!SAMPLEFORMAT_4;LogLuv 24 bits +!SAMPLEFORMAT_8;LogLuv 32 bits +!SAMPLEFORMAT_16;32 bits floating point !TP_CBDL_METHOD;Process located !TP_COLORAPP_FREE;Free temp+green + CAT02 + [output] !TP_COLORAPP_NEUTRAL;Reset !TP_COLORAPP_NEUTRAL_TIP;Reset all sliders checkbox and curves to their default values -!TP_COLORAPP_TEMP_TOOLTIP;To select an illuminant always Tint=1.\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\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504 !TP_COLORAPP_YB;Yb% (mean luminance) !TP_COLORAPP_YBSCENE;Yb% (mean luminance) !TP_COLORAPP_YBSCENE_TOOLTIP;if auto enable, Yb is calculated from the mean value of actual image luminance @@ -2117,6 +2139,9 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_RETINEX_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positives values (max).\nOrdinate: amplification or reduction. !TP_RETINEX_VIEW_MASK;Mask !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_TM_FATTAL_AMOUNT;Amount +!TP_TM_FATTAL_LABEL;HDR Tone Mapping +!TP_TM_FATTAL_THRESHOLD;Threshold !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_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. diff --git a/rtdata/languages/Turkish b/rtdata/languages/Turkish index 74b38ed6c..937e0dabb 100644 --- a/rtdata/languages/Turkish +++ b/rtdata/languages/Turkish @@ -463,6 +463,7 @@ TP_WBALANCE_TEMPERATURE;Isı !EXIFFILTER_EXPOSURECOMPENSATION;Exposure compensation (EV) !EXIFFILTER_FILETYPE;File type !EXIFFILTER_METADATAFILTER;Enable metadata filters +!EXIFPANEL_SHOWALL;Show all !EXPORT_BYPASS;Processing steps to bypass !EXPORT_BYPASS_ALL;Select / Unselect All !EXPORT_BYPASS_DEFRINGE;Bypass Defringe @@ -585,7 +586,7 @@ TP_WBALANCE_TEMPERATURE;Isı !HISTORY_MSG_82;Profile changed !HISTORY_MSG_83;S/H - Sharp mask !HISTORY_MSG_84;Perspective correction -!HISTORY_MSG_85;LCP +!HISTORY_MSG_85;Lens Correction - LCP file !HISTORY_MSG_86;RGB Curves - Luminosity mode !HISTORY_MSG_87;Impulse Noise Reduction !HISTORY_MSG_88;Impulse NR threshold @@ -968,6 +969,12 @@ TP_WBALANCE_TEMPERATURE;Isı !HISTORY_MSG_482;CAM02 - Green scene !HISTORY_MSG_483;CAM02 - Yb scene !HISTORY_MSG_484;CAM02 - Auto Yb scene +!HISTORY_MSG_485;Lens Correction +!HISTORY_MSG_486;Lens Correction - Camera +!HISTORY_MSG_487;Lens Correction - Lens +!HISTORY_MSG_488;HDR Tone Mapping +!HISTORY_MSG_489;HDR TM - Threshold +!HISTORY_MSG_490;HDR TM - Amount !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider. !IPTCPANEL_CITYHINT;Enter the name of the city pictured in this image. @@ -994,6 +1001,10 @@ TP_WBALANCE_TEMPERATURE;Isı !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. +!LENSPROFILE_CORRECTION_AUTOMATCH;Auto-matched correction parameters +!LENSPROFILE_CORRECTION_LCPFILE;LCP File +!LENSPROFILE_CORRECTION_MANUAL;Manual correction parameters +!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. !MAIN_BUTTON_FULLSCREEN;Fullscreen !MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the next image relative to image opened in the Editor.\nShortcut: Shift-F4\n\nTo navigate to the next image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F4 !MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the previous image relative to image opened in the Editor.\nShortcut: Shift-F3\n\nTo navigate to the previous image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F3 @@ -1029,6 +1040,7 @@ TP_WBALANCE_TEMPERATURE;Isı !MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 9 !MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 !MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 9 +!MAIN_TOOLTIP_BACKCOLOR3;Background color of the preview: Middle grey\nShortcut: 9 !MAIN_TOOLTIP_BEFOREAFTERLOCK;Lock / Unlock the Before view\n\nLock: keep the Before view unchanged.\nUseful to evaluate the cumulative effect of multiple tools.\nAdditionally, comparisons can be made to any state in the History.\n\nUnlock: the Before view will follow the After view one step behind, showing the image before the effect of the currently used tool. !MAIN_TOOLTIP_PREVIEWB;Preview the Blue channel.\nShortcut: b !MAIN_TOOLTIP_PREVIEWFOCUSMASK;Preview the Focus Mask.\nShortcut: Shift-f\n\nMore accurate on images with shallow depth of field, low noise and at higher zoom levels.\n\nTo improve detection accuracy for noisy images evaluate at smaller zoom, about 10-30%. @@ -1079,7 +1091,7 @@ TP_WBALANCE_TEMPERATURE;Isı !PARTIALPASTE_HSVEQUALIZER;HSV equalizer !PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction !PARTIALPASTE_LABCURVE;L*a*b* adjustments -!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_LENSPROFILE;Profiled lens correction !PARTIALPASTE_PCVIGNETTE;Vignette filter !PARTIALPASTE_PERSPECTIVE;Perspective !PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter @@ -1099,11 +1111,12 @@ TP_WBALANCE_TEMPERATURE;Isı !PARTIALPASTE_RAW_FALSECOLOR;False color suppression !PARTIALPASTE_RAW_IMAGENUM;Sub-image !PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps -!PARTIALPASTE_RAW_PIXELSHIFT;PixelShift +!PARTIALPASTE_RAW_PIXELSHIFT;Pixel Shift !PARTIALPASTE_RETINEX;Retinex !PARTIALPASTE_RGBCURVES;RGB curves !PARTIALPASTE_SHARPENEDGE;Edges !PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_TM_FATTAL;HDR Tone mapping !PARTIALPASTE_VIBRANCE;Vibrance !PARTIALPASTE_WAVELETGROUP;Wavelet Levels !PREFERENCES_ADD;Add @@ -1113,6 +1126,7 @@ TP_WBALANCE_TEMPERATURE;Isı !PREFERENCES_AUTLISVLOW;None !PREFERENCES_AUTLOW;Low !PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +!PREFERENCES_AUTOSAVE_TP_OPEN;Automatically save tools collapsed/expanded\nstate before exiting !PREFERENCES_AUTSTD;Standard !PREFERENCES_BATCH_PROCESSING;Batch Processing !PREFERENCES_BEHADDALL;All to 'Add' @@ -1146,18 +1160,16 @@ TP_WBALANCE_TEMPERATURE;Isı !PREFERENCES_D55;5500K !PREFERENCES_D60;6000K !PREFERENCES_D65;6500K -!PREFERENCES_DARKFRAME;Dark-Frame !PREFERENCES_DARKFRAMEFOUND;Found !PREFERENCES_DARKFRAMESHOTS;shots !PREFERENCES_DARKFRAMETEMPLATES;templates !PREFERENCES_DAUB_LABEL;Use Daubechies D6 wavelets instead of D4 !PREFERENCES_DAUB_TOOLTIP;The Noise Reduction and Wavelet Levels tools use a Debauchies mother wavelet. If you choose D6 instead of D4 you increase the number of orthogonal Daubechies coefficients and probably increase quality of small-scale levels. There is no memory or processing time difference between the two. !PREFERENCES_DIRDARKFRAMES;Dark-frames directory +!PREFERENCES_DIRECTORIES;Directories !PREFERENCES_EDITORLAYOUT;Editor Layout !PREFERENCES_EXPAUT;Expert !PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar\n(de-select for low resolution display) -!PREFERENCES_FILMSIMULATION;Film Simulation -!PREFERENCES_FLATFIELD;Flat-Field !PREFERENCES_FLATFIELDFOUND;Found !PREFERENCES_FLATFIELDSDIR;Flat-fields directory !PREFERENCES_FLATFIELDSHOTS;shots @@ -1233,6 +1245,7 @@ TP_WBALANCE_TEMPERATURE;Isı !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_RGBDTL_LABEL;Max number of threads for Noise Reduction and Wavelet Levels !PREFERENCES_RGBDTL_TOOLTIP;Leave the setting at "0" to automatically use as many threads as possible. The more threads run in parallel, the faster the computation. Refer to RawPedia for memory requirements. +!PREFERENCES_SAVE_TP_OPEN_NOW;Save tools collapsed/expanded state now !PREFERENCES_SELECTFONT;Select main font !PREFERENCES_SELECTFONT_COLPICKER;Select Color Picker's font !PREFERENCES_SERIALIZE_TIFF_READ;Tiff Read Settings @@ -1282,6 +1295,15 @@ TP_WBALANCE_TEMPERATURE;Isı !PROGRESSBAR_PROCESSING_PROFILESAVED;Processing profile saved !PROGRESSBAR_SNAPSHOT_ADDED;Snapshot added !PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!QINFO_FRAMECOUNT;%2 frames +!QINFO_HDR;HDR / %2 frame(s) +!QINFO_PIXELSHIFT;Pixel Shift / %2 frame(s) +!SAMPLEFORMAT_0;Unknown data format +!SAMPLEFORMAT_1;Unsigned 8 bits +!SAMPLEFORMAT_2;Unsigned 16 bits +!SAMPLEFORMAT_4;LogLuv 24 bits +!SAMPLEFORMAT_8;LogLuv 32 bits +!SAMPLEFORMAT_16;32 bits floating point !SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists !SAVEDLG_FORCEFORMATOPTS;Force saving options !SAVEDLG_SUBSAMP;Subsampling @@ -1291,8 +1313,8 @@ TP_WBALANCE_TEMPERATURE;Isı !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. !SAVEDLG_WARNFILENAME;File will be named !SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. -!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the output profile. -!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate de rendering generated by the output profile of the ICM tool. Most useful for simulating printing outputs. +!SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the Printer profile. +!SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate the printer's output by using the Printer profile set in Preferences > Color Management. !THRESHOLDSELECTOR_B;Bottom !THRESHOLDSELECTOR_BL;Bottom-left !THRESHOLDSELECTOR_BR;Bottom-right @@ -1437,7 +1459,7 @@ TP_WBALANCE_TEMPERATURE;Isı !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 Tint=1.\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\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504 !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_WBCAM;WB [RT+CAT02] + [output] @@ -1701,7 +1723,7 @@ TP_WBALANCE_TEMPERATURE;Isı !TP_LENSGEOM_AUTOCROP;Auto-Crop !TP_LENSGEOM_FILL;Auto-fill !TP_LENSGEOM_LABEL;Lens / Geometry -!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_LABEL;Profiled Lens Correction !TP_LENSPROFILE_USECA;Chromatic aberration correction !TP_LENSPROFILE_USEDIST;Distortion correction !TP_LENSPROFILE_USEVIGN;Vignetting correction @@ -1924,6 +1946,9 @@ TP_WBALANCE_TEMPERATURE;Isı !TP_SHARPENMICRO_LABEL;Microcontrast !TP_SHARPENMICRO_MATRIX;3×3 matrix instead of 5×5 !TP_SHARPENMICRO_UNIFORMITY;Uniformity +!TP_TM_FATTAL_AMOUNT;Amount +!TP_TM_FATTAL_LABEL;HDR Tone Mapping +!TP_TM_FATTAL_THRESHOLD;Threshold !TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift !TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH !TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones diff --git a/rtdata/languages/default b/rtdata/languages/default index 1589c3573..120be7b4d 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -715,6 +715,12 @@ HISTORY_MSG_481;CAM02 - Temp scene HISTORY_MSG_482;CAM02 - Green scene HISTORY_MSG_483;CAM02 - Yb scene HISTORY_MSG_484;CAM02 - Auto Yb scene +HISTORY_MSG_485;Lens Correction +HISTORY_MSG_486;Lens Correction - Camera +HISTORY_MSG_487;Lens Correction - Lens +HISTORY_MSG_488;HDR Tone Mapping +HISTORY_MSG_489;HDR TM - Threshold +HISTORY_MSG_490;HDR TM - Amount HISTORY_NEWSNAPSHOT;Add HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s HISTORY_SNAPSHOT;Snapshot @@ -761,6 +767,10 @@ IPTCPANEL_TITLE;Title 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. +LENSPROFILE_CORRECTION_AUTOMATCH;Auto-matched correction parameters +LENSPROFILE_CORRECTION_LCPFILE;LCP File +LENSPROFILE_CORRECTION_MANUAL;Manual correction parameters +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. MAIN_BUTTON_FULLSCREEN;Fullscreen MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the next image relative to image opened in the Editor.\nShortcut: Shift-F4\n\nTo navigate to the next image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F4 MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the previous image relative to image opened in the Editor.\nShortcut: Shift-F3\n\nTo navigate to the previous image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F3 @@ -819,6 +829,7 @@ MAIN_TAB_WAVELET_TOOLTIP;Shortcut: Alt-w MAIN_TOOLTIP_BACKCOLOR0;Background color of the preview: Theme-based\nShortcut: 9 MAIN_TOOLTIP_BACKCOLOR1;Background color of the preview: Black\nShortcut: 9 MAIN_TOOLTIP_BACKCOLOR2;Background color of the preview: White\nShortcut: 9 +MAIN_TOOLTIP_BACKCOLOR3;Background color of the preview: Middle grey\nShortcut: 9 MAIN_TOOLTIP_BEFOREAFTERLOCK;Lock / Unlock the Before view\n\nLock: keep the Before view unchanged.\nUseful to evaluate the cumulative effect of multiple tools.\nAdditionally, comparisons can be made to any state in the History.\n\nUnlock: the Before view will follow the After view one step behind, showing the image before the effect of the currently used tool. MAIN_TOOLTIP_HIDEHP;Show/Hide the left panel (including the history).\nShortcut: l MAIN_TOOLTIP_INDCLIPPEDH;Clipped highlight indication.\nShortcut: < @@ -886,7 +897,7 @@ PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction PARTIALPASTE_IPTCINFO;IPTC PARTIALPASTE_LABCURVE;L*a*b* adjustments PARTIALPASTE_LENSGROUP;Lens Related Settings -PARTIALPASTE_LENSPROFILE;Lens correction profile +PARTIALPASTE_LENSPROFILE;Profiled lens correction PARTIALPASTE_METAGROUP;Metadata PARTIALPASTE_PCVIGNETTE;Vignette filter PARTIALPASTE_PERSPECTIVE;Perspective @@ -907,7 +918,7 @@ PARTIALPASTE_RAW_DMETHOD;Demosaic method PARTIALPASTE_RAW_FALSECOLOR;False color suppression PARTIALPASTE_RAW_IMAGENUM;Sub-image PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps -PARTIALPASTE_RAW_PIXELSHIFT;PixelShift +PARTIALPASTE_RAW_PIXELSHIFT;Pixel Shift PARTIALPASTE_RESIZE;Resize PARTIALPASTE_RETINEX;Retinex PARTIALPASTE_RGBCURVES;RGB curves @@ -916,6 +927,7 @@ PARTIALPASTE_SHADOWSHIGHLIGHTS;Shadows/highlights PARTIALPASTE_SHARPENEDGE;Edges PARTIALPASTE_SHARPENING;Sharpening (USM/RL) PARTIALPASTE_SHARPENMICRO;Microcontrast +PARTIALPASTE_TM_FATTAL;HDR Tone mapping PARTIALPASTE_VIBRANCE;Vibrance PARTIALPASTE_VIGNETTING;Vignetting correction PARTIALPASTE_WAVELETGROUP;Wavelet Levels @@ -928,6 +940,7 @@ PREFERENCES_AUTLISSTD;High PREFERENCES_AUTLISVLOW;None PREFERENCES_AUTLOW;Low PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +PREFERENCES_AUTOSAVE_TP_OPEN;Automatically save tools collapsed/expanded\nstate before exiting PREFERENCES_AUTSTD;Standard PREFERENCES_BATCH_PROCESSING;Batch Processing PREFERENCES_BEHADDALL;All to 'Add' @@ -968,7 +981,6 @@ PREFERENCES_D50_OLD;5000K PREFERENCES_D55;5500K PREFERENCES_D60;6000K PREFERENCES_D65;6500K -PREFERENCES_DARKFRAME;Dark-Frame PREFERENCES_DARKFRAMEFOUND;Found PREFERENCES_DARKFRAMESHOTS;shots PREFERENCES_DARKFRAMETEMPLATES;templates @@ -977,6 +989,7 @@ PREFERENCES_DATEFORMATHINT;You can use the following formatting strings:\n%y< PREFERENCES_DAUB_LABEL;Use Daubechies D6 wavelets instead of D4 PREFERENCES_DAUB_TOOLTIP;The Noise Reduction and Wavelet Levels tools use a Debauchies mother wavelet. If you choose D6 instead of D4 you increase the number of orthogonal Daubechies coefficients and probably increase quality of small-scale levels. There is no memory or processing time difference between the two. PREFERENCES_DIRDARKFRAMES;Dark-frames directory +PREFERENCES_DIRECTORIES;Directories PREFERENCES_DIRHOME;Home directory PREFERENCES_DIRLAST;Last visited directory PREFERENCES_DIROTHER;Other @@ -989,8 +1002,6 @@ PREFERENCES_EXTERNALEDITOR;External Editor PREFERENCES_FBROWSEROPTS;File Browser / Thumbnail Options PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar\n(de-select for low resolution display) PREFERENCES_FILEFORMAT;File format -PREFERENCES_FILMSIMULATION;Film Simulation -PREFERENCES_FLATFIELD;Flat-Field PREFERENCES_FLATFIELDFOUND;Found PREFERENCES_FLATFIELDSDIR;Flat-fields directory PREFERENCES_FLATFIELDSHOTS;shots @@ -1092,6 +1103,7 @@ 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_RGBDTL_LABEL;Max number of threads for Noise Reduction and Wavelet Levels PREFERENCES_RGBDTL_TOOLTIP;Leave the setting at "0" to automatically use as many threads as possible. The more threads run in parallel, the faster the computation. Refer to RawPedia for memory requirements. +PREFERENCES_SAVE_TP_OPEN_NOW;Save tools collapsed/expanded state now PREFERENCES_SELECTFONT;Select main font PREFERENCES_SELECTFONT_COLPICKER;Select Color Picker's font PREFERENCES_SELECTLANG;Select language @@ -1170,13 +1182,21 @@ PROGRESSBAR_SAVEPNG;Saving PNG file... PROGRESSBAR_SAVETIFF;Saving TIFF file... PROGRESSBAR_SNAPSHOT_ADDED;Snapshot added PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +QINFO_FRAMECOUNT;%2 frames +QINFO_HDR;HDR / %2 frame(s) QINFO_ISO;ISO QINFO_NOEXIF;Exif data not available. +QINFO_PIXELSHIFT;Pixel Shift / %2 frame(s) +SAMPLEFORMAT_0;Unknown data format +SAMPLEFORMAT_1;Unsigned 8 bits +SAMPLEFORMAT_2;Unsigned 16 bits +SAMPLEFORMAT_4;LogLuv 24 bits +SAMPLEFORMAT_8;LogLuv 32 bits +SAMPLEFORMAT_16;32 bits floating point SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists SAVEDLG_FILEFORMAT;File format SAVEDLG_FORCEFORMATOPTS;Force saving options SAVEDLG_JPEGQUAL;JPEG quality -SAVEDLG_PNGCOMPR;PNG compression SAVEDLG_PUTTOQUEUE;Put into processing queue SAVEDLG_PUTTOQUEUEHEAD;Put to the head of the processing queue SAVEDLG_PUTTOQUEUETAIL;Put to the end of the processing queue @@ -1190,8 +1210,8 @@ SAVEDLG_SUBSAMP_TOOLTIP;Best compression:\nJ:a:b 4:2:0\nh/v 2/2\nChroma halved h SAVEDLG_TIFFUNCOMPRESSED;Uncompressed TIFF SAVEDLG_WARNFILENAME;File will be named SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. -SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the output profile. -SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate de rendering generated by the output profile of the ICM tool. Most useful for simulating printing outputs. +SOFTPROOF_GAMUTCHECK_TOOLTIP;If active, indicates in grey the pixels which have out of gamut colors from the Printer profile. +SOFTPROOF_TOOLTIP;Soft-proofing\nIf active, let you simulate the printer's output by using the Printer profile set in Preferences > Color Management. THRESHOLDSELECTOR_B;Bottom THRESHOLDSELECTOR_BL;Bottom-left THRESHOLDSELECTOR_BR;Bottom-right @@ -1351,7 +1371,7 @@ 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 Tint=1.\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\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504 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_WBCAM;WB [RT+CAT02] + [output] @@ -1651,7 +1671,7 @@ TP_LABCURVE_RSTPRO_TOOLTIP;Works on the Chromaticity slider and the CC curve. TP_LENSGEOM_AUTOCROP;Auto-Crop TP_LENSGEOM_FILL;Auto-fill TP_LENSGEOM_LABEL;Lens / Geometry -TP_LENSPROFILE_LABEL;Lens Correction Profile +TP_LENSPROFILE_LABEL;Profiled Lens Correction TP_LENSPROFILE_USECA;Chromatic aberration correction TP_LENSPROFILE_USEDIST;Distortion correction TP_LENSPROFILE_USEVIGN;Vignetting correction @@ -1910,6 +1930,9 @@ TP_SHARPENMICRO_UNIFORMITY;Uniformity TP_SPOT_COUNTLABEL;%1 point(s) TP_SPOT_ENTRYCHANGED;Point changed TP_SPOT_LABEL;Spot removal +TP_TM_FATTAL_AMOUNT;Amount +TP_TM_FATTAL_LABEL;HDR Tone Mapping +TP_TM_FATTAL_THRESHOLD;Threshold TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones diff --git a/rtdata/themes/RawTherapee-GTK3-20_.css b/rtdata/themes/RawTherapee-GTK3-20_.css index ff780a4e3..b0a7ac071 100644 --- a/rtdata/themes/RawTherapee-GTK3-20_.css +++ b/rtdata/themes/RawTherapee-GTK3-20_.css @@ -31,7 +31,7 @@ scrollbar:not(.overlay-indicator):hover { color: #666666; } -.view:selected { +.view:selected:not(check):not(radio) { color: #262626; background-color: #AAAAAA } @@ -171,6 +171,7 @@ eventbox.frame { border-color: #565656; } +/*** Scrollbar ***************************************/ scrollbar { background-color: #303030; } @@ -181,6 +182,42 @@ scrollbar slider:hover { background-color: #999999; } +scrollbar:not(.overlay-indicator).horizontal slider, +scrollbar.horizontal.hovering slider { + min-height: 6px; + min-width: 24px; +} +scrollbar:not(.overlay-indicator).horizontal.fine-tune slider, +scrollbar.horizontal.hovering.fine-tune slider { + min-height: 4px; + border-width: 4px; + margin: 0 -1px; +} +scrollbar.horizontal.overlay-indicator:not(.hovering) slider { + min-width: 24px; + min-height: 3px; + margin: 0 2px; +} + +scrollbar:not(.overlay-indicator).vertical slider, +scrollbar.vertical.hovering slider { + min-height: 24px; + min-width: 6px; +} +scrollbar:not(.overlay-indicator).vertical.fine-tune slider, +scrollbar.vertical.hovering.fine-tune slider { + min-width: 4px; + border-width: 4px; + margin: -1px 0; +} +scrollbar.vertical.overlay-indicator:not(.hovering) slider { + min-width: 3px; + min-height: 24px; + margin: 2px 0; +} + +/**************************************************/ + button { padding: 0; min-height: 5px; @@ -639,18 +676,11 @@ paned box, paned grid { } paned > separator { - border-width: 1px; - border-color: #484848; - margin: 0; - padding: 0; -} -paned.horizontal > separator { - min-width: 2px; - border-style: none solid; -} -paned.vertical > separator { - min-height: 2px; - border-style: solid none; + border-width: 1px 1px 0 0; + border-style: solid; + border-color: #404040; + padding: 0px; + margin: 4px; } #PlacesPaned { @@ -873,3 +903,13 @@ paned.vertical > separator { #PartialPasteHeaderSep { background-color: #D8D8D8; } + +/* All MyFileChooserButtons */ +button#MyFileChooserButton { + padding: 2px; + margin: 2px; +} + +#ToolPanelNotebook button { + margin: 0px; +} diff --git a/rtdata/themes/RawTherapee-GTK3-_19.css b/rtdata/themes/RawTherapee-GTK3-_19.css index 8263dd857..8443768c3 100644 --- a/rtdata/themes/RawTherapee-GTK3-_19.css +++ b/rtdata/themes/RawTherapee-GTK3-_19.css @@ -500,3 +500,9 @@ GtkNotebook { #PartialPasteHeaderSep { color: #D8D8D8; } + + +#MyFileChooserButton { + padding-left: 3px; + padding-right: 3px; +} diff --git a/rtdata/themes/TooWaBlue-GTK3-20_.css b/rtdata/themes/TooWaBlue-GTK3-20_.css index e009c6d9a..1e196bff8 100644 --- a/rtdata/themes/TooWaBlue-GTK3-20_.css +++ b/rtdata/themes/TooWaBlue-GTK3-20_.css @@ -2,7 +2,7 @@ This file is part of RawTherapee. Copyright (c) 2016-2017 TooWaBoo - Version 2.53 - requires RT 5.0 (Gtk+ >= 3.20) + Version 2.60 RawTherapee is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -425,7 +425,7 @@ paned.horizontal > separator { } paned.vertical > separator { - background-image: image(@bg-dark-grey); + background-image: image(@bg-dark-grey); background-color: @bg-light-grey; min-height: 0.5em; border-top: 1px solid @bg-light-grey; @@ -463,6 +463,9 @@ menu separator { background-color: @view-grid-border; margin: 0.33334em 0; } +#MyFileChooserButton separator { + background-color: transparent; +} #PlacesPaned .view.separator { color: @border-color; @@ -884,12 +887,15 @@ window.csd:not(.fullscreen) #MainNotebook > header.top { border-radius: 0; } +#MetaPanelNotebook > stack > box:nth-child(1) > :nth-child(1) { + border: 0.08334em solid @bg-dark-grey; +} #MetaPanelNotebook > stack > box:nth-child(2) > scrolledwindow scrolledwindow { background-color: @bg-dark-grey; padding: 0; margin: 0; } -#MetaPanelNotebook .view { +#MetaPanelNotebook > stack > box:nth-child(2) .view { border: 0.08334em solid @bg-dark-grey; padding: 0.16667em; margin: 0; @@ -1035,36 +1041,9 @@ window.csd:not(.fullscreen) #MainNotebook > header.top { margin-right: 0; } -#EditorTopPanel > box:nth-child(9) > button.image-button:not(:nth-child(6)) { - min-width: 0; - padding-left: 0.33334em; - padding-right: 0.33334em; -} - -#EditorTopPanel > box:nth-child(9) > button.image-button:nth-child(6) { - -gtk-icon-shadow: none; -} -#EditorTopPanel > box > box > button { - min-height: 0.625em; - min-width: 0; - margin: 0 0.16667em; - padding: 0 0.16667em; - border: 0.08334em solid transparent; - background-color: transparent; - background-image: none; - box-shadow: none; -} -#EditorTopPanel > box > box > button:hover { - background-color: transparent; - background-image: none; - border: 0.08334em solid transparent; - box-shadow: none; -} -#EditorTopPanel > box > box > button:checked { - background-color: transparent; - background-image: none; - border: 0.08334em solid @bg-button-border; - box-shadow: none; +#EditorTopPanel > box:nth-child(9) > button.image-button { + min-width: 1.05em; + padding: 0; } /*Button editor bottom*/ @@ -1208,7 +1187,7 @@ entry > window > frame > border { padding: 0.08334em; border: 0.08334em solid @accent-color; } -.csd entry > window > frame > border { +entry > window > frame > border { margin: 0.08334em; } /* end */ @@ -1216,15 +1195,14 @@ entry > window > frame > border { /*** end ***************************************************************************************/ /*** Popover *** Context menu filechooser ******************************************************/ -.csd popover.background { - box-shadow: 0 1px 6px 1px rgba(0, 0, 0, 0.5), 0 0 0 1px @bg-dark-grey; -} + popover.background { background-color: @bg-dark-grey; border: 0.08334em solid @accent-color; border-radius: 0; padding: 0; margin: 0; + box-shadow: 0 1px 6px 1px rgba(0, 0, 0, 0.5), 0 0 0 1px @bg-dark-grey; } popover.background > box { padding: 0; @@ -1266,6 +1244,21 @@ button.text-button label { margin: 0 0.5em;/* x */ } +#PrefNotebook > stack > :nth-child(5) combobox { + /* margin: 0.16667em 0; */ + margin: 2px 0; +} +#PrefNotebook > stack > :nth-child(2) #MyFileChooserButton { + /* margin: 0.25em 0.33334em; */ + margin: 3px 5px; +} + +filechooser button image, +#MyFileChooserButton image { + opacity: .8; + -gtk-icon-style: symbolic; +} + #MainNotebook > header > grid > button, button.flat { border: 0.08334em solid transparent; @@ -1370,6 +1363,10 @@ dialog button, padding: 0 0.375em; margin: 0.08334em 0; } +#MyExpander #MyFileChooserButton + button.image-button{ + min-width: 1.66667em; + padding: 0; +} combobox .combo, dialog combobox .combo, #ToolPanelNotebook combobox .combo, @@ -1389,7 +1386,6 @@ dialog combobox .combo, #MyExpander combobox + label */ { margin-left: 0.16667em; } -#MyExpander label + filechooserbutton, #MyExpander label + * > button:not(.flat).Left, #MyExpander label + combobox:not(:first-child):not(:only-child), #MyExpander label + button:not(.flat):not(spinbutton) { @@ -1640,6 +1636,10 @@ radiobutton { margin: 0; min-height: 2em; } +#PrefNotebook checkbox, +#PrefNotebook checkbutton { + min-height: 1.6667em; +} check, radio { @@ -1653,7 +1653,7 @@ radio { box-shadow: none; background-repeat: no-repeat; -gtk-icon-shadow: none; - color: @text-color; + color: @text-color; } radiobutton label, checkbutton label { @@ -1863,5 +1863,4 @@ headerbar:backdrop { headerbar .title:backdrop { color: alpha(@winTitle,.60); } -/**/ /*** end ***************************************************************************************/ diff --git a/rtengine/CA_correct_RT.cc b/rtengine/CA_correct_RT.cc index aea20d8c9..59fd804f1 100644 --- a/rtengine/CA_correct_RT.cc +++ b/rtengine/CA_correct_RT.cc @@ -113,7 +113,7 @@ using namespace rtengine; void RawImageSource::CA_correct_RT(const bool autoCA, const double cared, const double cablue, const double caautostrength, array2D &rawData) { -// multithreaded and partly vectorized by Ingo Weyrich +// multithreaded and vectorized by Ingo Weyrich constexpr int ts = 128; constexpr int tsh = ts / 2; //shifts to location of vertical and diagonal neighbors @@ -134,12 +134,12 @@ void RawImageSource::CA_correct_RT(const bool autoCA, const double cared, const } // local variables - const int width = W, height = H; + const int width = W + (W & 1), height = H; //temporary array to store simple interpolation of G - float *Gtmp = (float (*)) calloc ((height) * (width), sizeof * Gtmp); + float *Gtmp = (float (*)) malloc ((height * width) / 2 * sizeof * Gtmp); // temporary array to avoid race conflicts, only every second pixel needs to be saved here - float *RawDataTmp = (float*) malloc( (height * width + ((height * width) & 1)) * sizeof(float) / 2); + float *RawDataTmp = (float*) malloc( (height * width) * sizeof(float) / 2); float blockave[2][2] = {{0, 0}, {0, 0}}, blocksqave[2][2] = {{0, 0}, {0, 0}}, blockdenom[2][2] = {{0, 0}, {0, 0}}, blockvar[2][2]; @@ -185,7 +185,7 @@ void RawImageSource::CA_correct_RT(const bool autoCA, const double cared, const float blockavethr[2][2] = {{0, 0}, {0, 0}}, blocksqavethr[2][2] = {{0, 0}, {0, 0}}, blockdenomthr[2][2] = {{0, 0}, {0, 0}}; // assign working space - constexpr int buffersize = 3 * sizeof(float) * ts * ts + 6 * sizeof(float) * ts * tsh + 8 * 64 + 63; + constexpr int buffersize = sizeof(float) * ts * ts + 8 * sizeof(float) * ts * tsh + 8 * 64 + 63; char *buffer = (char *) malloc(buffersize); char *data = (char*)( ( uintptr_t(buffer) + uintptr_t(63)) / 64 * 64); @@ -194,22 +194,21 @@ void RawImageSource::CA_correct_RT(const bool autoCA, const double cared, const //rgb data in a tile float* rgb[3]; rgb[0] = (float (*)) data; - rgb[1] = (float (*)) (data + 1 * sizeof(float) * ts * ts + 1 * 64); - rgb[2] = (float (*)) (data + 2 * sizeof(float) * ts * ts + 2 * 64); + rgb[1] = (float (*)) (data + sizeof(float) * ts * tsh + 1 * 64); + rgb[2] = (float (*)) (data + sizeof(float) * (ts * ts + ts * tsh) + 2 * 64); //high pass filter for R/B in vertical direction - float *rbhpfh = (float (*)) (data + 3 * sizeof(float) * ts * ts + 3 * 64); + float *rbhpfh = (float (*)) (data + 2 * sizeof(float) * ts * ts + 3 * 64); //high pass filter for R/B in horizontal direction - float *rbhpfv = (float (*)) (data + 3 * sizeof(float) * ts * ts + sizeof(float) * ts * tsh + 4 * 64); + float *rbhpfv = (float (*)) (data + 2 * sizeof(float) * ts * ts + sizeof(float) * ts * tsh + 4 * 64); //low pass filter for R/B in horizontal direction - float *rblpfh = (float (*)) (data + 4 * sizeof(float) * ts * ts + 5 * 64); + float *rblpfh = (float (*)) (data + 3 * sizeof(float) * ts * ts + 5 * 64); //low pass filter for R/B in vertical direction - float *rblpfv = (float (*)) (data + 4 * sizeof(float) * ts * ts + sizeof(float) * ts * tsh + 6 * 64); + float *rblpfv = (float (*)) (data + 3 * sizeof(float) * ts * ts + sizeof(float) * ts * tsh + 6 * 64); //low pass filter for colour differences in horizontal direction - float *grblpfh = (float (*)) (data + 5 * sizeof(float) * ts * ts + 7 * 64); + float *grblpfh = (float (*)) (data + 4 * sizeof(float) * ts * ts + 7 * 64); //low pass filter for colour differences in vertical direction - float *grblpfv = (float (*)) (data + 5 * sizeof(float) * ts * ts + sizeof(float) * ts * tsh + 8 * 64); - //colour differences + float *grblpfv = (float (*)) (data + 4 * sizeof(float) * ts * ts + sizeof(float) * ts * tsh + 8 * 64); float *grbdiff = rbhpfh; // there is no overlap in buffer usage => share //green interpolated to optical sample points for R/B float *gshift = rbhpfv; // there is no overlap in buffer usage => share @@ -236,13 +235,38 @@ void RawImageSource::CA_correct_RT(const bool autoCA, const double cared, const // rgb values should be floating point numbers between 0 and 1 // after white balance multipliers are applied - for (int rr = rrmin; rr < rrmax; rr++) - for (int row = rr + top, cc = ccmin; cc < ccmax; cc++) { - int col = cc + left; +#ifdef __SSE2__ + vfloat c65535v = F2V(65535.f); +#endif + + for (int rr = rrmin; rr < rrmax; rr++) { + int row = rr + top; + int cc = ccmin; + int col = cc + left; +#ifdef __SSE2__ + int c0 = FC(rr, cc); + if(c0 == 1) { + rgb[c0][rr * ts + cc] = rawData[row][col] / 65535.f; + cc++; + col++; + c0 = FC(rr, cc); + } + int indx1 = rr * ts + cc; + for (; cc < ccmax - 7; cc+=8, col+=8, indx1 += 8) { + vfloat val1 = LVFU(rawData[row][col]) / c65535v; + vfloat val2 = LVFU(rawData[row][col + 4]) / c65535v; + vfloat nonGreenv = _mm_shuffle_ps(val1,val2,_MM_SHUFFLE( 2,0,2,0 )); + STVFU(rgb[c0][indx1 >> 1], nonGreenv); + STVFU(rgb[1][indx1], val1); + STVFU(rgb[1][indx1 + 4], val2); + } +#endif + for (; cc < ccmax; cc++, col++) { int c = FC(rr, cc); int indx1 = rr * ts + cc; - rgb[c][indx1] = (rawData[row][col]) / 65535.0f; + rgb[c][indx1 >> ((c & 1) ^ 1)] = rawData[row][col] / 65535.f; } + } // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //fill borders @@ -250,7 +274,7 @@ void RawImageSource::CA_correct_RT(const bool autoCA, const double cared, const for (int rr = 0; rr < border; rr++) for (int cc = ccmin; cc < ccmax; cc++) { int c = FC(rr, cc); - rgb[c][rr * ts + cc] = rgb[c][(border2 - rr) * ts + cc]; + rgb[c][(rr * ts + cc) >> ((c & 1) ^ 1)] = rgb[c][((border2 - rr) * ts + cc) >> ((c & 1) ^ 1)]; } } @@ -258,7 +282,7 @@ void RawImageSource::CA_correct_RT(const bool autoCA, const double cared, const for (int rr = 0; rr < border; rr++) for (int cc = ccmin; cc < ccmax; cc++) { int c = FC(rr, cc); - rgb[c][(rrmax + rr)*ts + cc] = (rawData[(height - rr - 2)][left + cc]) / 65535.0f; + rgb[c][((rrmax + rr)*ts + cc) >> ((c & 1) ^ 1)] = rawData[(height - rr - 2)][left + cc] / 65535.f; } } @@ -266,7 +290,7 @@ void RawImageSource::CA_correct_RT(const bool autoCA, const double cared, const for (int rr = rrmin; rr < rrmax; rr++) for (int cc = 0; cc < border; cc++) { int c = FC(rr, cc); - rgb[c][rr * ts + cc] = rgb[c][rr * ts + border2 - cc]; + rgb[c][(rr * ts + cc) >> ((c & 1) ^ 1)] = rgb[c][(rr * ts + border2 - cc) >> ((c & 1) ^ 1)]; } } @@ -274,7 +298,7 @@ void RawImageSource::CA_correct_RT(const bool autoCA, const double cared, const for (int rr = rrmin; rr < rrmax; rr++) for (int cc = 0; cc < border; cc++) { int c = FC(rr, cc); - rgb[c][rr * ts + ccmax + cc] = (rawData[(top + rr)][(width - cc - 2)]) / 65535.0f; + rgb[c][(rr * ts + ccmax + cc) >> ((c & 1) ^ 1)] = rawData[(top + rr)][(width - cc - 2)] / 65535.f; } } @@ -283,7 +307,7 @@ void RawImageSource::CA_correct_RT(const bool autoCA, const double cared, const for (int rr = 0; rr < border; rr++) for (int cc = 0; cc < border; cc++) { int c = FC(rr, cc); - rgb[c][(rr)*ts + cc] = (rawData[border2 - rr][border2 - cc]) / 65535.0f; + rgb[c][(rr * ts + cc) >> ((c & 1) ^ 1)] = rawData[border2 - rr][border2 - cc] / 65535.f; } } @@ -291,7 +315,7 @@ void RawImageSource::CA_correct_RT(const bool autoCA, const double cared, const for (int rr = 0; rr < border; rr++) for (int cc = 0; cc < border; cc++) { int c = FC(rr, cc); - rgb[c][(rrmax + rr)*ts + ccmax + cc] = (rawData[(height - rr - 2)][(width - cc - 2)]) / 65535.0f; + rgb[c][((rrmax + rr)*ts + ccmax + cc) >> ((c & 1) ^ 1)] = rawData[(height - rr - 2)][(width - cc - 2)] / 65535.f; } } @@ -299,7 +323,7 @@ void RawImageSource::CA_correct_RT(const bool autoCA, const double cared, const for (int rr = 0; rr < border; rr++) for (int cc = 0; cc < border; cc++) { int c = FC(rr, cc); - rgb[c][(rr)*ts + ccmax + cc] = (rawData[(border2 - rr)][(width - cc - 2)]) / 65535.0f; + rgb[c][(rr * ts + ccmax + cc) >> ((c & 1) ^ 1)] = rawData[(border2 - rr)][(width - cc - 2)] / 65535.f; } } @@ -307,7 +331,7 @@ void RawImageSource::CA_correct_RT(const bool autoCA, const double cared, const for (int rr = 0; rr < border; rr++) for (int cc = 0; cc < border; cc++) { int c = FC(rr, cc); - rgb[c][(rrmax + rr)*ts + cc] = (rawData[(height - rr - 2)][(border2 - cc)]) / 65535.0f; + rgb[c][((rrmax + rr)*ts + cc) >> ((c & 1) ^ 1)] = rawData[(height - rr - 2)][(border2 - cc)] / 65535.f; } } @@ -328,30 +352,45 @@ void RawImageSource::CA_correct_RT(const bool autoCA, const double cared, const #ifdef __SSE2__ for (; cc < cc1 - 9; cc+=8, indx+=8) { //compute directional weights using image gradients - vfloat wtuv = onev / SQRV(epsv + vabsf(LC2VFU(rgb[1][indx + v1]) - LC2VFU(rgb[1][indx - v1])) + vabsf(LC2VFU(rgb[c][indx]) - LC2VFU(rgb[c][indx - v2])) + vabsf(LC2VFU(rgb[1][indx - v1]) - LC2VFU(rgb[1][indx - v3]))); - vfloat wtdv = onev / SQRV(epsv + vabsf(LC2VFU(rgb[1][indx - v1]) - LC2VFU(rgb[1][indx + v1])) + vabsf(LC2VFU(rgb[c][indx]) - LC2VFU(rgb[c][indx + v2])) + vabsf(LC2VFU(rgb[1][indx + v1]) - LC2VFU(rgb[1][indx + v3]))); - vfloat wtlv = onev / SQRV(epsv + vabsf(LC2VFU(rgb[1][indx + 1]) - LC2VFU(rgb[1][indx - 1])) + vabsf(LC2VFU(rgb[c][indx]) - LC2VFU(rgb[c][indx - 2])) + vabsf(LC2VFU(rgb[1][indx - 1]) - LC2VFU(rgb[1][indx - 3]))); - vfloat wtrv = onev / SQRV(epsv + vabsf(LC2VFU(rgb[1][indx - 1]) - LC2VFU(rgb[1][indx + 1])) + vabsf(LC2VFU(rgb[c][indx]) - LC2VFU(rgb[c][indx + 2])) + vabsf(LC2VFU(rgb[1][indx + 1]) - LC2VFU(rgb[1][indx + 3]))); + vfloat rgb1mv1v = LC2VFU(rgb[1][indx - v1]); + vfloat rgb1pv1v = LC2VFU(rgb[1][indx + v1]); + vfloat rgbcv = LVFU(rgb[c][indx >> 1]); + vfloat temp1v = epsv + vabsf(rgb1mv1v - rgb1pv1v); + vfloat wtuv = onev / SQRV(temp1v + vabsf(rgbcv - LVFU(rgb[c][(indx - v2) >> 1])) + vabsf(rgb1mv1v - LC2VFU(rgb[1][indx - v3]))); + vfloat wtdv = onev / SQRV(temp1v + vabsf(rgbcv - LVFU(rgb[c][(indx + v2) >> 1])) + vabsf(rgb1pv1v - LC2VFU(rgb[1][indx + v3]))); + vfloat rgb1m1v = LC2VFU(rgb[1][indx - 1]); + vfloat rgb1p1v = LC2VFU(rgb[1][indx + 1]); + vfloat temp2v = epsv + vabsf(rgb1m1v - rgb1p1v); + vfloat wtlv = onev / SQRV(temp2v + vabsf(rgbcv - LVFU(rgb[c][(indx - 2) >> 1])) + vabsf(rgb1m1v - LC2VFU(rgb[1][indx - 3]))); + vfloat wtrv = onev / SQRV(temp2v + vabsf(rgbcv - LVFU(rgb[c][(indx + 2) >> 1])) + vabsf(rgb1p1v - LC2VFU(rgb[1][indx + 3]))); //store in rgb array the interpolated G value at R/B grid points using directional weighted average - STC2VFU(rgb[1][indx], (wtuv * LC2VFU(rgb[1][indx - v1]) + wtdv * LC2VFU(rgb[1][indx + v1]) + wtlv * LC2VFU(rgb[1][indx - 1]) + wtrv * LC2VFU(rgb[1][indx + 1])) / (wtuv + wtdv + wtlv + wtrv)); + STC2VFU(rgb[1][indx], (wtuv * rgb1mv1v + wtdv * rgb1pv1v + wtlv * rgb1m1v + wtrv * rgb1p1v) / (wtuv + wtdv + wtlv + wtrv)); } #endif for (; cc < cc1 - 3; cc+=2, indx+=2) { //compute directional weights using image gradients - float wtu = 1.f / SQR(eps + fabsf(rgb[1][indx + v1] - rgb[1][indx - v1]) + fabsf(rgb[c][indx] - rgb[c][indx - v2]) + fabsf(rgb[1][indx - v1] - rgb[1][indx - v3])); - float wtd = 1.f / SQR(eps + fabsf(rgb[1][indx - v1] - rgb[1][indx + v1]) + fabsf(rgb[c][indx] - rgb[c][indx + v2]) + fabsf(rgb[1][indx + v1] - rgb[1][indx + v3])); - float wtl = 1.f / SQR(eps + fabsf(rgb[1][indx + 1] - rgb[1][indx - 1]) + fabsf(rgb[c][indx] - rgb[c][indx - 2]) + fabsf(rgb[1][indx - 1] - rgb[1][indx - 3])); - float wtr = 1.f / SQR(eps + fabsf(rgb[1][indx - 1] - rgb[1][indx + 1]) + fabsf(rgb[c][indx] - rgb[c][indx + 2]) + fabsf(rgb[1][indx + 1] - rgb[1][indx + 3])); + float wtu = 1.f / SQR(eps + fabsf(rgb[1][indx + v1] - rgb[1][indx - v1]) + fabsf(rgb[c][indx >> 1] - rgb[c][(indx - v2) >> 1]) + fabsf(rgb[1][indx - v1] - rgb[1][indx - v3])); + float wtd = 1.f / SQR(eps + fabsf(rgb[1][indx - v1] - rgb[1][indx + v1]) + fabsf(rgb[c][indx >> 1] - rgb[c][(indx + v2) >> 1]) + fabsf(rgb[1][indx + v1] - rgb[1][indx + v3])); + float wtl = 1.f / SQR(eps + fabsf(rgb[1][indx + 1] - rgb[1][indx - 1]) + fabsf(rgb[c][indx >> 1] - rgb[c][(indx - 2) >> 1]) + fabsf(rgb[1][indx - 1] - rgb[1][indx - 3])); + float wtr = 1.f / SQR(eps + fabsf(rgb[1][indx - 1] - rgb[1][indx + 1]) + fabsf(rgb[c][indx >> 1] - rgb[c][(indx + 2) >> 1]) + fabsf(rgb[1][indx + 1] - rgb[1][indx + 3])); //store in rgb array the interpolated G value at R/B grid points using directional weighted average rgb[1][indx] = (wtu * rgb[1][indx - v1] + wtd * rgb[1][indx + v1] + wtl * rgb[1][indx - 1] + wtr * rgb[1][indx + 1]) / (wtu + wtd + wtl + wtr); } if (row > -1 && row < height) { - for(int col = max(left + 3, 0), indx = rr * ts + 3 - (left < 0 ? (left+3) : 0); col < min(cc1 + left - 3, width); col++, indx++) { - Gtmp[row * width + col] = rgb[1][indx]; + int offset = (FC(row,max(left + 3, 0)) & 1); + int col = max(left + 3, 0) + offset; + int indx = rr * ts + 3 - (left < 0 ? (left+3) : 0) + offset; +#ifdef __SSE2__ + for(; col < min(cc1 + left - 3, width) - 7; col+=8, indx+=8) { + STVFU(Gtmp[(row * width + col) >> 1], LC2VFU(rgb[1][indx])); + } +#endif + for(; col < min(cc1 + left - 3, width); col+=2, indx+=2) { + Gtmp[(row * width + col) >> 1] = rgb[1][indx]; } } @@ -361,47 +400,53 @@ void RawImageSource::CA_correct_RT(const bool autoCA, const double cared, const vfloat zd25v = F2V(0.25f); #endif for (int rr = 4; rr < rr1 - 4; rr++) { - int cc = 4 + (FC(rr, 2) & 1), indx = rr * ts + cc, c = FC(rr, cc); + int cc = 4 + (FC(rr, 2) & 1); + int indx = rr * ts + cc; + int c = FC(rr, cc); #ifdef __SSE2__ for (; cc < cc1 - 10; cc += 8, indx += 8) { vfloat rgb1v = LC2VFU(rgb[1][indx]); - vfloat rgbcv = LC2VFU(rgb[c][indx]); - vfloat temp1v = vabsf(vabsf((rgb1v - rgbcv) - (LC2VFU(rgb[1][indx + v4]) - LC2VFU(rgb[c][indx + v4]))) + - vabsf(LC2VFU(rgb[1][indx - v4]) - LC2VFU(rgb[c][indx - v4]) - rgb1v + rgbcv) - - vabsf(LC2VFU(rgb[1][indx - v4]) - LC2VFU(rgb[c][indx - v4]) - LC2VFU(rgb[1][indx + v4]) + LC2VFU(rgb[c][indx + v4]))); + vfloat rgbcv = LVFU(rgb[c][indx >> 1]); + vfloat rgb1mv4 = LC2VFU(rgb[1][indx - v4]); + vfloat rgb1pv4 = LC2VFU(rgb[1][indx + v4]); + vfloat temp1v = vabsf(vabsf((rgb1v - rgbcv) - (rgb1pv4 - LVFU(rgb[c][(indx + v4) >> 1]))) + + vabsf(rgb1mv4 - LVFU(rgb[c][(indx - v4) >> 1]) - rgb1v + rgbcv) - + vabsf(rgb1mv4 - LVFU(rgb[c][(indx - v4) >> 1]) - rgb1pv4 + LVFU(rgb[c][(indx + v4) >> 1]))); STVFU(rbhpfv[indx >> 1], temp1v); - vfloat temp2v = vabsf(vabsf((rgb1v - rgbcv) - (LC2VFU(rgb[1][indx + 4]) - LC2VFU(rgb[c][indx + 4]))) + - vabsf(LC2VFU(rgb[1][indx - 4]) - LC2VFU(rgb[c][indx - 4]) - rgb1v + rgbcv) - - vabsf(LC2VFU(rgb[1][indx - 4]) - LC2VFU(rgb[c][indx - 4]) - LC2VFU(rgb[1][indx + 4]) + LC2VFU(rgb[c][indx + 4]))); + vfloat rgb1m4 = LC2VFU(rgb[1][indx - 4]); + vfloat rgb1p4 = LC2VFU(rgb[1][indx + 4]); + vfloat temp2v = vabsf(vabsf((rgb1v - rgbcv) - (rgb1p4 - LVFU(rgb[c][(indx + 4) >> 1]))) + + vabsf(rgb1m4 - LVFU(rgb[c][(indx - 4) >> 1]) - rgb1v + rgbcv) - + vabsf(rgb1m4 - LVFU(rgb[c][(indx - 4) >> 1]) - rgb1p4 + LVFU(rgb[c][(indx + 4) >> 1]))); STVFU(rbhpfh[indx >> 1], temp2v); //low and high pass 1D filters of G in vertical/horizontal directions rgb1v = vmul2f(rgb1v); - vfloat glpfvv = zd25v * (rgb1v + LC2VFU(rgb[1][indx + v2]) + LC2VFU(rgb[1][indx - v2])); - vfloat glpfhv = zd25v * (rgb1v + LC2VFU(rgb[1][indx + 2]) + LC2VFU(rgb[1][indx - 2])); + vfloat glpfvv = (rgb1v + LC2VFU(rgb[1][indx + v2]) + LC2VFU(rgb[1][indx - v2])); + vfloat glpfhv = (rgb1v + LC2VFU(rgb[1][indx + 2]) + LC2VFU(rgb[1][indx - 2])); rgbcv = vmul2f(rgbcv); - STVFU(rblpfv[indx >> 1], epsv + vabsf(glpfvv - zd25v * (rgbcv + LC2VFU(rgb[c][indx + v2]) + LC2VFU(rgb[c][indx - v2])))); - STVFU(rblpfh[indx >> 1], epsv + vabsf(glpfhv - zd25v * (rgbcv + LC2VFU(rgb[c][indx + 2]) + LC2VFU(rgb[c][indx - 2])))); - STVFU(grblpfv[indx >> 1], glpfvv + zd25v * (rgbcv + LC2VFU(rgb[c][indx + v2]) + LC2VFU(rgb[c][indx - v2]))); - STVFU(grblpfh[indx >> 1], glpfhv + zd25v * (rgbcv + LC2VFU(rgb[c][indx + 2]) + LC2VFU(rgb[c][indx - 2]))); + STVFU(rblpfv[indx >> 1], zd25v * vabsf(glpfvv - (rgbcv + LVFU(rgb[c][(indx + v2) >> 1]) + LVFU(rgb[c][(indx - v2) >> 1])))); + STVFU(rblpfh[indx >> 1], zd25v * vabsf(glpfhv - (rgbcv + LVFU(rgb[c][(indx + 2) >> 1]) + LVFU(rgb[c][(indx - 2) >> 1])))); + STVFU(grblpfv[indx >> 1], zd25v * (glpfvv + (rgbcv + LVFU(rgb[c][(indx + v2) >> 1]) + LVFU(rgb[c][(indx - v2) >> 1])))); + STVFU(grblpfh[indx >> 1], zd25v * (glpfhv + (rgbcv + LVFU(rgb[c][(indx + 2) >> 1]) + LVFU(rgb[c][(indx - 2) >> 1])))); } #endif for (; cc < cc1 - 4; cc += 2, indx += 2) { - rbhpfv[indx >> 1] = fabsf(fabsf((rgb[1][indx] - rgb[c][indx]) - (rgb[1][indx + v4] - rgb[c][indx + v4])) + - fabsf((rgb[1][indx - v4] - rgb[c][indx - v4]) - (rgb[1][indx] - rgb[c][indx])) - - fabsf((rgb[1][indx - v4] - rgb[c][indx - v4]) - (rgb[1][indx + v4] - rgb[c][indx + v4]))); - rbhpfh[indx >> 1] = fabsf(fabsf((rgb[1][indx] - rgb[c][indx]) - (rgb[1][indx + 4] - rgb[c][indx + 4])) + - fabsf((rgb[1][indx - 4] - rgb[c][indx - 4]) - (rgb[1][indx] - rgb[c][indx])) - - fabsf((rgb[1][indx - 4] - rgb[c][indx - 4]) - (rgb[1][indx + 4] - rgb[c][indx + 4]))); + rbhpfv[indx >> 1] = fabsf(fabsf((rgb[1][indx] - rgb[c][indx >> 1]) - (rgb[1][indx + v4] - rgb[c][(indx + v4) >> 1])) + + fabsf((rgb[1][indx - v4] - rgb[c][(indx - v4) >> 1]) - (rgb[1][indx] - rgb[c][indx >> 1])) - + fabsf((rgb[1][indx - v4] - rgb[c][(indx - v4) >> 1]) - (rgb[1][indx + v4] - rgb[c][(indx + v4) >> 1]))); + rbhpfh[indx >> 1] = fabsf(fabsf((rgb[1][indx] - rgb[c][indx >> 1]) - (rgb[1][indx + 4] - rgb[c][(indx + 4) >> 1])) + + fabsf((rgb[1][indx - 4] - rgb[c][(indx - 4) >> 1]) - (rgb[1][indx] - rgb[c][indx >> 1])) - + fabsf((rgb[1][indx - 4] - rgb[c][(indx - 4) >> 1]) - (rgb[1][indx + 4] - rgb[c][(indx + 4) >> 1]))); //low and high pass 1D filters of G in vertical/horizontal directions - float glpfv = 0.25f * (2.f * rgb[1][indx] + rgb[1][indx + v2] + rgb[1][indx - v2]); - float glpfh = 0.25f * (2.f * rgb[1][indx] + rgb[1][indx + 2] + rgb[1][indx - 2]); - rblpfv[indx >> 1] = eps + fabsf(glpfv - 0.25f * (2.f * rgb[c][indx] + rgb[c][indx + v2] + rgb[c][indx - v2])); - rblpfh[indx >> 1] = eps + fabsf(glpfh - 0.25f * (2.f * rgb[c][indx] + rgb[c][indx + 2] + rgb[c][indx - 2])); - grblpfv[indx >> 1] = glpfv + 0.25f * (2.f * rgb[c][indx] + rgb[c][indx + v2] + rgb[c][indx - v2]); - grblpfh[indx >> 1] = glpfh + 0.25f * (2.f * rgb[c][indx] + rgb[c][indx + 2] + rgb[c][indx - 2]); + float glpfv = (2.f * rgb[1][indx] + rgb[1][indx + v2] + rgb[1][indx - v2]); + float glpfh = (2.f * rgb[1][indx] + rgb[1][indx + 2] + rgb[1][indx - 2]); + rblpfv[indx >> 1] = 0.25f * fabsf(glpfv - (2.f * rgb[c][indx >> 1] + rgb[c][(indx + v2) >> 1] + rgb[c][(indx - v2) >> 1])); + rblpfh[indx >> 1] = 0.25f * fabsf(glpfh - (2.f * rgb[c][indx >> 1] + rgb[c][(indx + 2) >> 1] + rgb[c][(indx - 2) >> 1])); + grblpfv[indx >> 1] = 0.25f * (glpfv + (2.f * rgb[c][indx >> 1] + rgb[c][(indx + v2) >> 1] + rgb[c][(indx - v2) >> 1])); + grblpfh[indx >> 1] = 0.25f * (glpfh + (2.f * rgb[c][indx >> 1] + rgb[c][(indx + 2) >> 1] + rgb[c][(indx - 2) >> 1])); } } @@ -414,10 +459,9 @@ void RawImageSource::CA_correct_RT(const bool autoCA, const double cared, const } #ifdef __SSE2__ - vfloat zd3125v = F2V(0.3125f); - vfloat zd09375v = F2V(0.09375f); + vfloat zd3v = F2V(0.3f); vfloat zd1v = F2V(0.1f); - vfloat zd125v = F2V(0.125f); + vfloat zd5v = F2V(0.5f); #endif // along line segments, find the point along each segment that minimizes the colour variance @@ -439,29 +483,27 @@ void RawImageSource::CA_correct_RT(const bool autoCA, const double cared, const //solve for the interpolation position that minimizes colour difference variance over the tile //vertical - vfloat gdiffv = zd3125v * (LC2VFU(rgb[1][indx + ts]) - LC2VFU(rgb[1][indx - ts])) + zd09375v * (LC2VFU(rgb[1][indx + ts + 1]) - LC2VFU(rgb[1][indx - ts + 1]) + LC2VFU(rgb[1][indx + ts - 1]) - LC2VFU(rgb[1][indx - ts - 1])); - vfloat deltgrbv = LC2VFU(rgb[c][indx]) - LC2VFU(rgb[1][indx]); + vfloat temp1 = zd3v * (LC2VFU(rgb[1][indx + ts + 1]) - LC2VFU(rgb[1][indx - ts - 1])); + vfloat temp2 = zd3v * (LC2VFU(rgb[1][indx - ts + 1]) - LC2VFU(rgb[1][indx + ts - 1])); + vfloat gdiffvv = (LC2VFU(rgb[1][indx + ts]) - LC2VFU(rgb[1][indx - ts])) + (temp1 - temp2); + vfloat deltgrbv = LVFU(rgb[c][indx >> 1]) - LC2VFU(rgb[1][indx]); - vfloat gradwtv = vabsf(zd25v * LVFU(rbhpfv[indx >> 1]) + zd125v * (LVFU(rbhpfv[(indx >> 1) + 1]) + LVFU(rbhpfv[(indx >> 1) - 1])) ) * (LVFU(grblpfv[(indx >> 1) - v1]) + LVFU(grblpfv[(indx >> 1) + v1])) / (epsv + zd1v * (LVFU(grblpfv[(indx >> 1) - v1]) + LVFU(grblpfv[(indx >> 1) + v1])) + LVFU(rblpfv[(indx >> 1) - v1]) + LVFU(rblpfv[(indx >> 1) + v1])); + vfloat gradwtvv = (LVFU(rbhpfv[indx >> 1]) + zd5v * (LVFU(rbhpfv[(indx >> 1) + 1]) + LVFU(rbhpfv[(indx >> 1) - 1]))) * (LVFU(grblpfv[(indx >> 1) - v1]) + LVFU(grblpfv[(indx >> 1) + v1])) / (epsv + zd1v * (LVFU(grblpfv[(indx >> 1) - v1]) + LVFU(grblpfv[(indx >> 1) + v1])) + LVFU(rblpfv[(indx >> 1) - v1]) + LVFU(rblpfv[(indx >> 1) + v1])); - coeff00v += gradwtv * deltgrbv * deltgrbv; - coeff01v += gradwtv * gdiffv * deltgrbv; - coeff02v += gradwtv * gdiffv * gdiffv; + coeff00v += gradwtvv * deltgrbv * deltgrbv; + coeff01v += gradwtvv * gdiffvv * deltgrbv; + coeff02v += gradwtvv * gdiffvv * gdiffvv; //horizontal - gdiffv = zd3125v * (LC2VFU(rgb[1][indx + 1]) - LC2VFU(rgb[1][indx - 1])) + zd09375v * (LC2VFU(rgb[1][indx + 1 + ts]) - LC2VFU(rgb[1][indx - 1 + ts]) + LC2VFU(rgb[1][indx + 1 - ts]) - LC2VFU(rgb[1][indx - 1 - ts])); + vfloat gdiffhv = (LC2VFU(rgb[1][indx + 1]) - LC2VFU(rgb[1][indx - 1])) + (temp1 + temp2); - gradwtv = vabsf(zd25v * LVFU(rbhpfh[indx >> 1]) + zd125v * (LVFU(rbhpfh[(indx >> 1) + v1]) + LVFU(rbhpfh[(indx >> 1) - v1])) ) * (LVFU(grblpfh[(indx >> 1) - 1]) + LVFU(grblpfh[(indx >> 1) + 1])) / (epsv + zd1v * (LVFU(grblpfh[(indx >> 1) - 1]) + LVFU(grblpfh[(indx >> 1) + 1])) + LVFU(rblpfh[(indx >> 1) - 1]) + LVFU(rblpfh[(indx >> 1) + 1])); + vfloat gradwthv = (LVFU(rbhpfh[indx >> 1]) + zd5v * (LVFU(rbhpfh[(indx >> 1) + v1]) + LVFU(rbhpfh[(indx >> 1) - v1]))) * (LVFU(grblpfh[(indx >> 1) - 1]) + LVFU(grblpfh[(indx >> 1) + 1])) / (epsv + zd1v * (LVFU(grblpfh[(indx >> 1) - 1]) + LVFU(grblpfh[(indx >> 1) + 1])) + LVFU(rblpfh[(indx >> 1) - 1]) + LVFU(rblpfh[(indx >> 1) + 1])); - coeff10v += gradwtv * deltgrbv * deltgrbv; - coeff11v += gradwtv * gdiffv * deltgrbv; - coeff12v += gradwtv * gdiffv * gdiffv; - - // In Mathematica, - // f[x_]=Expand[Total[Flatten[ - // ((1-x) RotateLeft[Gint,shift1]+x RotateLeft[Gint,shift2]-cfapad)^2[[dv;;-1;;2,dh;;-1;;2]]]]]; - // extremum = -.5Coefficient[f[x],x]/Coefficient[f[x],x^2] + coeff10v += gradwthv * deltgrbv * deltgrbv; + coeff11v += gradwthv * gdiffhv * deltgrbv; + coeff12v += gradwthv * gdiffhv * gdiffhv; } + coeff[0][0][c>>1] += vhadd(coeff00v); coeff[0][1][c>>1] += vhadd(coeff01v); coeff[0][2][c>>1] += vhadd(coeff02v); @@ -476,19 +518,19 @@ void RawImageSource::CA_correct_RT(const bool autoCA, const double cared, const //solve for the interpolation position that minimizes colour difference variance over the tile //vertical - float gdiff = 0.3125f * (rgb[1][indx + ts] - rgb[1][indx - ts]) + 0.09375f * (rgb[1][indx + ts + 1] - rgb[1][indx - ts + 1] + rgb[1][indx + ts - 1] - rgb[1][indx - ts - 1]); - float deltgrb = (rgb[c][indx] - rgb[1][indx]); + float gdiff = (rgb[1][indx + ts] - rgb[1][indx - ts]) + 0.3f * (rgb[1][indx + ts + 1] - rgb[1][indx - ts + 1] + rgb[1][indx + ts - 1] - rgb[1][indx - ts - 1]); + float deltgrb = (rgb[c][indx >> 1] - rgb[1][indx]); - float gradwt = fabsf(0.25f * rbhpfv[indx >> 1] + 0.125f * (rbhpfv[(indx >> 1) + 1] + rbhpfv[(indx >> 1) - 1]) ) * (grblpfv[(indx >> 1) - v1] + grblpfv[(indx >> 1) + v1]) / (eps + 0.1f * (grblpfv[(indx >> 1) - v1] + grblpfv[(indx >> 1) + v1]) + rblpfv[(indx >> 1) - v1] + rblpfv[(indx >> 1) + v1]); + float gradwt = (rbhpfv[indx >> 1] + 0.5f * (rbhpfv[(indx >> 1) + 1] + rbhpfv[(indx >> 1) - 1]) ) * (grblpfv[(indx >> 1) - v1] + grblpfv[(indx >> 1) + v1]) / (eps + 0.1f * (grblpfv[(indx >> 1) - v1] + grblpfv[(indx >> 1) + v1]) + rblpfv[(indx >> 1) - v1] + rblpfv[(indx >> 1) + v1]); coeff[0][0][c>>1] += gradwt * deltgrb * deltgrb; coeff[0][1][c>>1] += gradwt * gdiff * deltgrb; coeff[0][2][c>>1] += gradwt * gdiff * gdiff; //horizontal - gdiff = 0.3125f * (rgb[1][indx + 1] - rgb[1][indx - 1]) + 0.09375f * (rgb[1][indx + 1 + ts] - rgb[1][indx - 1 + ts] + rgb[1][indx + 1 - ts] - rgb[1][indx - 1 - ts]); + gdiff = (rgb[1][indx + 1] - rgb[1][indx - 1]) + 0.3f * (rgb[1][indx + 1 + ts] - rgb[1][indx - 1 + ts] + rgb[1][indx + 1 - ts] - rgb[1][indx - 1 - ts]); - gradwt = fabsf(0.25f * rbhpfh[indx >> 1] + 0.125f * (rbhpfh[(indx >> 1) + v1] + rbhpfh[(indx >> 1) - v1]) ) * (grblpfh[(indx >> 1) - 1] + grblpfh[(indx >> 1) + 1]) / (eps + 0.1f * (grblpfh[(indx >> 1) - 1] + grblpfh[(indx >> 1) + 1]) + rblpfh[(indx >> 1) - 1] + rblpfh[(indx >> 1) + 1]); + gradwt = (rbhpfh[indx >> 1] + 0.5f * (rbhpfh[(indx >> 1) + v1] + rbhpfh[(indx >> 1) - v1]) ) * (grblpfh[(indx >> 1) - 1] + grblpfh[(indx >> 1) + 1]) / (eps + 0.1f * (grblpfh[(indx >> 1) - 1] + grblpfh[(indx >> 1) + 1]) + rblpfh[(indx >> 1) - 1] + rblpfh[(indx >> 1) + 1]); coeff[1][0][c>>1] += gradwt * deltgrb * deltgrb; coeff[1][1][c>>1] += gradwt * gdiff * deltgrb; @@ -501,6 +543,19 @@ void RawImageSource::CA_correct_RT(const bool autoCA, const double cared, const } } + for (int dir = 0; dir < 2; dir++) { + for (int k = 0; k < 3; k++) { + for (int c = 0; c < 2; c++) { + coeff[dir][k][c] *= 0.25f; + if(k == 1) { + coeff[dir][k][c] *= 0.3125f; + } else if(k == 2) { + coeff[dir][k][c] *= SQR(0.3125f); + } + } + } + } + for (int c = 0; c < 2; c++) { for (int dir = 0; dir < 2; dir++) { // vert/hor @@ -719,36 +774,63 @@ void RawImageSource::CA_correct_RT(const bool autoCA, const double cared, const // rgb values should be floating point number between 0 and 1 // after white balance multipliers are applied - for (int rr = rrmin; rr < rrmax; rr++) - for (int row = rr + top, cc = ccmin; cc < ccmax; cc++) { - int col = cc + left; +#ifdef __SSE2__ + vfloat c65535v = F2V(65535.f); + vmask gmask = _mm_set_epi32(0, 0xffffffff, 0, 0xffffffff); +#endif + for (int rr = rrmin; rr < rrmax; rr++) { + int row = rr + top; + int cc = ccmin; + int col = cc + left; + int indx = row * width + col; + int indx1 = rr * ts + cc; +#ifdef __SSE2__ + int c = FC(rr, cc); + if(c & 1) { + rgb[1][indx1] = rawData[row][col] / 65535.f; + indx++; + indx1++; + cc++; + col++; + c = FC(rr, cc); + } + for (; cc < ccmax - 7; cc += 8, col += 8, indx += 8, indx1 += 8) { + vfloat val1v = LVFU(rawData[row][col]) / c65535v; + vfloat val2v = LVFU(rawData[row][col + 4]) / c65535v; + STVFU(rgb[c][indx1 >> 1], _mm_shuffle_ps(val1v, val2v, _MM_SHUFFLE(2, 0, 2, 0))); + vfloat gtmpv = LVFU(Gtmp[indx >> 1]); + STVFU(rgb[1][indx1], vself(gmask, PERMUTEPS(gtmpv, _MM_SHUFFLE(1, 1, 0, 0)), val1v)); + STVFU(rgb[1][indx1 + 4], vself(gmask, PERMUTEPS(gtmpv, _MM_SHUFFLE(3, 3, 2, 2)), val2v)); + } +#endif + for (; cc < ccmax; cc++, col++, indx++, indx1++) { int c = FC(rr, cc); - int indx = row * width + col; - int indx1 = rr * ts + cc; - rgb[c][indx1] = (rawData[row][col]) / 65535.0f; + rgb[c][indx1 >> ((c & 1) ^ 1)] = rawData[row][col] / 65535.f; if ((c & 1) == 0) { - rgb[1][indx1] = Gtmp[indx]; + rgb[1][indx1] = Gtmp[indx >> 1]; } } - + } // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //fill borders if (rrmin > 0) { for (int rr = 0; rr < border; rr++) for (int cc = ccmin; cc < ccmax; cc++) { int c = FC(rr, cc); - rgb[c][rr * ts + cc] = rgb[c][(border2 - rr) * ts + cc]; + rgb[c][(rr * ts + cc) >> ((c & 1) ^ 1)] = rgb[c][((border2 - rr) * ts + cc) >> ((c & 1) ^ 1)]; rgb[1][rr * ts + cc] = rgb[1][(border2 - rr) * ts + cc]; } } if (rrmax < rr1) { - for (int rr = 0; rr < border; rr++) + for (int rr = 0; rr < std::min(border, rr1 - rrmax); rr++) for (int cc = ccmin; cc < ccmax; cc++) { int c = FC(rr, cc); - rgb[c][(rrmax + rr)*ts + cc] = (rawData[(height - rr - 2)][left + cc]) / 65535.0f; - rgb[1][(rrmax + rr)*ts + cc] = Gtmp[(height - rr - 2) * width + left + cc]; + rgb[c][((rrmax + rr)*ts + cc) >> ((c & 1) ^ 1)] = (rawData[(height - rr - 2)][left + cc]) / 65535.f; + if ((c & 1) == 0) { + rgb[1][(rrmax + rr)*ts + cc] = Gtmp[((height - rr - 2) * width + left + cc) >> 1]; + } } } @@ -756,17 +838,19 @@ void RawImageSource::CA_correct_RT(const bool autoCA, const double cared, const for (int rr = rrmin; rr < rrmax; rr++) for (int cc = 0; cc < border; cc++) { int c = FC(rr, cc); - rgb[c][rr * ts + cc] = rgb[c][rr * ts + border2 - cc]; + rgb[c][(rr * ts + cc) >> ((c & 1) ^ 1)] = rgb[c][(rr * ts + border2 - cc) >> ((c & 1) ^ 1)]; rgb[1][rr * ts + cc] = rgb[1][rr * ts + border2 - cc]; } } if (ccmax < cc1) { for (int rr = rrmin; rr < rrmax; rr++) - for (int cc = 0; cc < border; cc++) { + for (int cc = 0; cc < std::min(border, cc1 - ccmax); cc++) { int c = FC(rr, cc); - rgb[c][rr * ts + ccmax + cc] = (rawData[(top + rr)][(width - cc - 2)]) / 65535.0f; - rgb[1][rr * ts + ccmax + cc] = Gtmp[(top + rr) * width + (width - cc - 2)]; + rgb[c][(rr * ts + ccmax + cc) >> ((c & 1) ^ 1)] = (rawData[(top + rr)][(width - cc - 2)]) / 65535.f; + if ((c & 1) == 0) { + rgb[1][rr * ts + ccmax + cc] = Gtmp[((top + rr) * width + (width - cc - 2)) >> 1]; + } } } @@ -775,35 +859,43 @@ void RawImageSource::CA_correct_RT(const bool autoCA, const double cared, const for (int rr = 0; rr < border; rr++) for (int cc = 0; cc < border; cc++) { int c = FC(rr, cc); - rgb[c][(rr)*ts + cc] = (rawData[border2 - rr][border2 - cc]) / 65535.0f; - rgb[1][(rr)*ts + cc] = Gtmp[(border2 - rr) * width + border2 - cc]; + rgb[c][(rr * ts + cc) >> ((c & 1) ^ 1)] = (rawData[border2 - rr][border2 - cc]) / 65535.f; + if ((c & 1) == 0) { + rgb[1][rr * ts + cc] = Gtmp[((border2 - rr) * width + border2 - cc) >> 1]; + } } } if (rrmax < rr1 && ccmax < cc1) { - for (int rr = 0; rr < border; rr++) - for (int cc = 0; cc < border; cc++) { + for (int rr = 0; rr < std::min(border, rr1 - rrmax); rr++) + for (int cc = 0; cc < std::min(border, cc1 - ccmax); cc++) { int c = FC(rr, cc); - rgb[c][(rrmax + rr)*ts + ccmax + cc] = (rawData[(height - rr - 2)][(width - cc - 2)]) / 65535.0f; - rgb[1][(rrmax + rr)*ts + ccmax + cc] = Gtmp[(height - rr - 2) * width + (width - cc - 2)]; + rgb[c][((rrmax + rr)*ts + ccmax + cc) >> ((c & 1) ^ 1)] = (rawData[(height - rr - 2)][(width - cc - 2)]) / 65535.f; + if ((c & 1) == 0) { + rgb[1][(rrmax + rr)*ts + ccmax + cc] = Gtmp[((height - rr - 2) * width + (width - cc - 2)) >> 1]; + } } } if (rrmin > 0 && ccmax < cc1) { for (int rr = 0; rr < border; rr++) - for (int cc = 0; cc < border; cc++) { + for (int cc = 0; cc < std::min(border, cc1 - ccmax); cc++) { int c = FC(rr, cc); - rgb[c][(rr)*ts + ccmax + cc] = (rawData[(border2 - rr)][(width - cc - 2)]) / 65535.0f; - rgb[1][(rr)*ts + ccmax + cc] = Gtmp[(border2 - rr) * width + (width - cc - 2)]; + rgb[c][(rr * ts + ccmax + cc) >> ((c & 1) ^ 1)] = (rawData[(border2 - rr)][(width - cc - 2)]) / 65535.f; + if ((c & 1) == 0) { + rgb[1][rr * ts + ccmax + cc] = Gtmp[((border2 - rr) * width + (width - cc - 2)) >> 1]; + } } } if (rrmax < rr1 && ccmin > 0) { - for (int rr = 0; rr < border; rr++) + for (int rr = 0; rr < std::min(border, rr1 - rrmax); rr++) for (int cc = 0; cc < border; cc++) { int c = FC(rr, cc); - rgb[c][(rrmax + rr)*ts + cc] = (rawData[(height - rr - 2)][(border2 - cc)]) / 65535.0f; - rgb[1][(rrmax + rr)*ts + cc] = Gtmp[(height - rr - 2) * width + (border2 - cc)]; + rgb[c][((rrmax + rr)*ts + cc) >> ((c & 1) ^ 1)] = (rawData[(height - rr - 2)][(border2 - cc)]) / 65535.f; + if ((c & 1) == 0) { + rgb[1][(rrmax + rr)*ts + cc] = Gtmp[((height - rr - 2) * width + (border2 - cc)) >> 1]; + } } } @@ -813,24 +905,20 @@ void RawImageSource::CA_correct_RT(const bool autoCA, const double cared, const if (!autoCA) { //manual CA correction; use red/blue slider values to set CA shift parameters for (int rr = 3; rr < rr1 - 3; rr++) - for (int row = rr + top, cc = 3, indx = rr * ts + cc; cc < cc1 - 3; cc++, indx++) { - int col = cc + left; + for (int cc = 3, indx = rr * ts + cc; cc < cc1 - 3; cc++, indx++) { int c = FC(rr, cc); if (c != 1) { //compute directional weights using image gradients - float wtu = 1.0 / SQR(eps + fabsf(rgb[1][(rr + 1) * ts + cc] - rgb[1][(rr - 1) * ts + cc]) + fabsf(rgb[c][(rr) * ts + cc] - rgb[c][(rr - 2) * ts + cc]) + fabsf(rgb[1][(rr - 1) * ts + cc] - rgb[1][(rr - 3) * ts + cc])); - float wtd = 1.0 / SQR(eps + fabsf(rgb[1][(rr - 1) * ts + cc] - rgb[1][(rr + 1) * ts + cc]) + fabsf(rgb[c][(rr) * ts + cc] - rgb[c][(rr + 2) * ts + cc]) + fabsf(rgb[1][(rr + 1) * ts + cc] - rgb[1][(rr + 3) * ts + cc])); - float wtl = 1.0 / SQR(eps + fabsf(rgb[1][(rr) * ts + cc + 1] - rgb[1][(rr) * ts + cc - 1]) + fabsf(rgb[c][(rr) * ts + cc] - rgb[c][(rr) * ts + cc - 2]) + fabsf(rgb[1][(rr) * ts + cc - 1] - rgb[1][(rr) * ts + cc - 3])); - float wtr = 1.0 / SQR(eps + fabsf(rgb[1][(rr) * ts + cc - 1] - rgb[1][(rr) * ts + cc + 1]) + fabsf(rgb[c][(rr) * ts + cc] - rgb[c][(rr) * ts + cc + 2]) + fabsf(rgb[1][(rr) * ts + cc + 1] - rgb[1][(rr) * ts + cc + 3])); + float wtu = 1.f / SQR(eps + fabsf(rgb[1][(rr + 1) * ts + cc] - rgb[1][(rr - 1) * ts + cc]) + fabsf(rgb[c][(rr * ts + cc) >> 1] - rgb[c][((rr - 2) * ts + cc) >> 1]) + fabsf(rgb[1][(rr - 1) * ts + cc] - rgb[1][(rr - 3) * ts + cc])); + float wtd = 1.f / SQR(eps + fabsf(rgb[1][(rr - 1) * ts + cc] - rgb[1][(rr + 1) * ts + cc]) + fabsf(rgb[c][(rr * ts + cc) >> 1] - rgb[c][((rr + 2) * ts + cc) >> 1]) + fabsf(rgb[1][(rr + 1) * ts + cc] - rgb[1][(rr + 3) * ts + cc])); + float wtl = 1.f / SQR(eps + fabsf(rgb[1][rr * ts + cc + 1] - rgb[1][rr * ts + cc - 1]) + fabsf(rgb[c][(rr * ts + cc) >> 1] - rgb[c][(rr * ts + cc - 2) >> 1]) + fabsf(rgb[1][rr * ts + cc - 1] - rgb[1][rr * ts + cc - 3])); + float wtr = 1.f / SQR(eps + fabsf(rgb[1][rr * ts + cc - 1] - rgb[1][rr * ts + cc + 1]) + fabsf(rgb[c][(rr * ts + cc) >> 1] - rgb[c][(rr * ts + cc + 2) >> 1]) + fabsf(rgb[1][rr * ts + cc + 1] - rgb[1][rr * ts + cc + 3])); //store in rgb array the interpolated G value at R/B grid points using directional weighted average rgb[1][indx] = (wtu * rgb[1][indx - v1] + wtd * rgb[1][indx + v1] + wtl * rgb[1][indx - 1] + wtr * rgb[1][indx + 1]) / (wtu + wtd + wtl + wtr); } - if (row > -1 && row < height && col > -1 && col < width) { - Gtmp[row * width + col] = rgb[1][indx]; - } } float hfrac = -((float)(hblock - 0.5) / (hblsz - 2) - 0.5); @@ -884,34 +972,39 @@ void RawImageSource::CA_correct_RT(const bool autoCA, const double cared, const for (int rr = 4; rr < rr1 - 4; rr++) { int cc = 4 + (FC(rr, 2) & 1); int c = FC(rr, cc); + int indx = (rr * ts + cc) >> 1; + int indxfc = (rr + shiftvfloor[c]) * ts + cc + shifthceil[c]; + int indxff = (rr + shiftvfloor[c]) * ts + cc + shifthfloor[c]; + int indxcc = (rr + shiftvceil[c]) * ts + cc + shifthceil[c]; + int indxcf = (rr + shiftvceil[c]) * ts + cc + shifthfloor[c]; #ifdef __SSE2__ vfloat shifthfracv = F2V(shifthfrac[c]); vfloat shiftvfracv = F2V(shiftvfrac[c]); - for (; cc < cc1 - 10; cc += 8) { + for (; cc < cc1 - 10; cc += 8, indxfc += 8, indxff += 8, indxcc += 8, indxcf += 8, indx += 4) { //perform CA correction using colour ratios or colour differences - vfloat Ginthfloorv = vintpf(shifthfracv, LC2VFU(rgb[1][(rr + shiftvfloor[c]) * ts + cc + shifthceil[c]]), LC2VFU(rgb[1][(rr + shiftvfloor[c]) * ts + cc + shifthfloor[c]])); - vfloat Ginthceilv = vintpf(shifthfracv, LC2VFU(rgb[1][(rr + shiftvceil[c]) * ts + cc + shifthceil[c]]), LC2VFU(rgb[1][(rr + shiftvceil[c]) * ts + cc + shifthfloor[c]])); + vfloat Ginthfloorv = vintpf(shifthfracv, LC2VFU(rgb[1][indxfc]), LC2VFU(rgb[1][indxff])); + vfloat Ginthceilv = vintpf(shifthfracv, LC2VFU(rgb[1][indxcc]), LC2VFU(rgb[1][indxcf])); //Gint is bilinear interpolation of G at CA shift point vfloat Gintv = vintpf(shiftvfracv, Ginthceilv, Ginthfloorv); //determine R/B at grid points using colour differences at shift point plus interpolated G value at grid point //but first we need to interpolate G-R/G-B to grid points... - STVFU(grbdiff[((rr)*ts + cc) >> 1], Gintv - LC2VFU(rgb[c][(rr) * ts + cc])); - STVFU(gshift[((rr)*ts + cc) >> 1], Gintv); + STVFU(grbdiff[indx], Gintv - LVFU(rgb[c][indx])); + STVFU(gshift[indx], Gintv); } #endif - for (; cc < cc1 - 4; cc += 2) { + for (; cc < cc1 - 4; cc += 2, indxfc += 2, indxff += 2, indxcc += 2, indxcf += 2, ++indx) { //perform CA correction using colour ratios or colour differences - float Ginthfloor = intp(shifthfrac[c], rgb[1][(rr + shiftvfloor[c]) * ts + cc + shifthceil[c]], rgb[1][(rr + shiftvfloor[c]) * ts + cc + shifthfloor[c]]); - float Ginthceil = intp(shifthfrac[c], rgb[1][(rr + shiftvceil[c]) * ts + cc + shifthceil[c]], rgb[1][(rr + shiftvceil[c]) * ts + cc + shifthfloor[c]]); + float Ginthfloor = intp(shifthfrac[c], rgb[1][indxfc], rgb[1][indxff]); + float Ginthceil = intp(shifthfrac[c], rgb[1][indxcc], rgb[1][indxcf]); //Gint is bilinear interpolation of G at CA shift point float Gint = intp(shiftvfrac[c], Ginthceil, Ginthfloor); //determine R/B at grid points using colour differences at shift point plus interpolated G value at grid point //but first we need to interpolate G-R/G-B to grid points... - grbdiff[((rr)*ts + cc) >> 1] = Gint - rgb[c][(rr) * ts + cc]; - gshift[((rr)*ts + cc) >> 1] = Gint; + grbdiff[indx] = Gint - rgb[c][indx]; + gshift[indx] = Gint; } } @@ -920,54 +1013,105 @@ void RawImageSource::CA_correct_RT(const bool autoCA, const double cared, const shiftvfrac[0] /= 2.f; shiftvfrac[2] /= 2.f; - // this loop does not deserve vectorization in mainly because the most expensive part with the divisions does not happen often (less than 1/10 in my tests) - for (int rr = 8; rr < rr1 - 8; rr++) - for (int cc = 8 + (FC(rr, 2) & 1), c = FC(rr, cc), indx = rr * ts + cc; cc < cc1 - 8; cc += 2, indx += 2) { +#ifdef __SSE2__ + vfloat zd25v = F2V(0.25f); + vfloat onev = F2V(1.f); + vfloat zd5v = F2V(0.5f); + vfloat epsv = F2V(eps); +#endif + for (int rr = 8; rr < rr1 - 8; rr++) { + int cc = 8 + (FC(rr, 2) & 1); + int c = FC(rr, cc); + int GRBdir0 = GRBdir[0][c]; + int GRBdir1 = GRBdir[1][c]; +#ifdef __SSE2__ + vfloat shifthfracc = F2V(shifthfrac[c]); + vfloat shiftvfracc = F2V(shiftvfrac[c]); + for (int indx = rr * ts + cc; cc < cc1 - 14; cc += 8, indx += 8) { + //interpolate colour difference from optical R/B locations to grid locations + vfloat grbdiffinthfloor = vintpf(shifthfracc, LVFU(grbdiff[(indx - GRBdir1) >> 1]), LVFU(grbdiff[indx >> 1])); + vfloat grbdiffinthceil = vintpf(shifthfracc, LVFU(grbdiff[((rr - GRBdir0) * ts + cc - GRBdir1) >> 1]), LVFU(grbdiff[((rr - GRBdir0) * ts + cc) >> 1])); + //grbdiffint is bilinear interpolation of G-R/G-B at grid point + vfloat grbdiffint = vintpf(shiftvfracc, grbdiffinthceil, grbdiffinthfloor); - float grbdiffold = rgb[1][indx] - rgb[c][indx]; + //now determine R/B at grid points using interpolated colour differences and interpolated G value at grid point + vfloat cinv = LVFU(rgb[c][indx >> 1]); + vfloat rinv = LC2VFU(rgb[1][indx]); + vfloat RBint = rinv - grbdiffint; + vmask cmask = vmaskf_ge(vabsf(RBint - cinv), zd25v * (RBint + cinv)); + if(_mm_movemask_ps((vfloat)cmask)) { + // if for any of the 4 pixels the condition is true, do the math for all 4 pixels and mask the unused out at the end + //gradient weights using difference from G at CA shift points and G at grid points + vfloat p0 = onev / (epsv + vabsf(rinv - LVFU(gshift[indx >> 1]))); + vfloat p1 = onev / (epsv + vabsf(rinv - LVFU(gshift[(indx - GRBdir1) >> 1]))); + vfloat p2 = onev / (epsv + vabsf(rinv - LVFU(gshift[((rr - GRBdir0) * ts + cc) >> 1]))); + vfloat p3 = onev / (epsv + vabsf(rinv - LVFU(gshift[((rr - GRBdir0) * ts + cc - GRBdir1) >> 1]))); + + grbdiffint = vself(cmask, (p0 * LVFU(grbdiff[indx >> 1]) + p1 * LVFU(grbdiff[(indx - GRBdir1) >> 1]) + + p2 * LVFU(grbdiff[((rr - GRBdir0) * ts + cc) >> 1]) + p3 * LVFU(grbdiff[((rr - GRBdir0) * ts + cc - GRBdir1) >> 1])) / (p0 + p1 + p2 + p3), grbdiffint); + + } + vfloat grbdiffold = rinv - cinv; + RBint = rinv - grbdiffint; + RBint = vself(vmaskf_gt(vabsf(grbdiffold), vabsf(grbdiffint)), RBint, cinv); + RBint = vself(vmaskf_lt(grbdiffold * grbdiffint, ZEROV), rinv - zd5v * (grbdiffold + grbdiffint), RBint); + STVFU(rgb[c][indx >> 1], RBint); + } +#endif + for (int c = FC(rr, cc), indx = rr * ts + cc; cc < cc1 - 8; cc += 2, indx += 2) { + float grbdiffold = rgb[1][indx] - rgb[c][indx >> 1]; //interpolate colour difference from optical R/B locations to grid locations - float grbdiffinthfloor = intp(shifthfrac[c], grbdiff[(indx - GRBdir[1][c]) >> 1], grbdiff[indx >> 1]); - float grbdiffinthceil = intp(shifthfrac[c], grbdiff[((rr - GRBdir[0][c]) * ts + cc - GRBdir[1][c]) >> 1], grbdiff[((rr - GRBdir[0][c]) * ts + cc) >> 1]); + float grbdiffinthfloor = intp(shifthfrac[c], grbdiff[(indx - GRBdir1) >> 1], grbdiff[indx >> 1]); + float grbdiffinthceil = intp(shifthfrac[c], grbdiff[((rr - GRBdir0) * ts + cc - GRBdir1) >> 1], grbdiff[((rr - GRBdir0) * ts + cc) >> 1]); //grbdiffint is bilinear interpolation of G-R/G-B at grid point float grbdiffint = intp(shiftvfrac[c], grbdiffinthceil, grbdiffinthfloor); //now determine R/B at grid points using interpolated colour differences and interpolated G value at grid point float RBint = rgb[1][indx] - grbdiffint; - if (fabsf(RBint - rgb[c][indx]) < 0.25f * (RBint + rgb[c][indx])) { + if (fabsf(RBint - rgb[c][indx >> 1]) < 0.25f * (RBint + rgb[c][indx >> 1])) { if (fabsf(grbdiffold) > fabsf(grbdiffint) ) { - rgb[c][indx] = RBint; + rgb[c][indx >> 1] = RBint; } } else { //gradient weights using difference from G at CA shift points and G at grid points - float p0 = 1.0f / (eps + fabsf(rgb[1][indx] - gshift[indx >> 1])); - float p1 = 1.0f / (eps + fabsf(rgb[1][indx] - gshift[(indx - GRBdir[1][c]) >> 1])); - float p2 = 1.0f / (eps + fabsf(rgb[1][indx] - gshift[((rr - GRBdir[0][c]) * ts + cc) >> 1])); - float p3 = 1.0f / (eps + fabsf(rgb[1][indx] - gshift[((rr - GRBdir[0][c]) * ts + cc - GRBdir[1][c]) >> 1])); + float p0 = 1.f / (eps + fabsf(rgb[1][indx] - gshift[indx >> 1])); + float p1 = 1.f / (eps + fabsf(rgb[1][indx] - gshift[(indx - GRBdir1) >> 1])); + float p2 = 1.f / (eps + fabsf(rgb[1][indx] - gshift[((rr - GRBdir0) * ts + cc) >> 1])); + float p3 = 1.f / (eps + fabsf(rgb[1][indx] - gshift[((rr - GRBdir0) * ts + cc - GRBdir1) >> 1])); - grbdiffint = (p0 * grbdiff[indx >> 1] + p1 * grbdiff[(indx - GRBdir[1][c]) >> 1] + - p2 * grbdiff[((rr - GRBdir[0][c]) * ts + cc) >> 1] + p3 * grbdiff[((rr - GRBdir[0][c]) * ts + cc - GRBdir[1][c]) >> 1]) / (p0 + p1 + p2 + p3) ; + grbdiffint = (p0 * grbdiff[indx >> 1] + p1 * grbdiff[(indx - GRBdir1) >> 1] + + p2 * grbdiff[((rr - GRBdir0) * ts + cc) >> 1] + p3 * grbdiff[((rr - GRBdir0) * ts + cc - GRBdir1) >> 1]) / (p0 + p1 + p2 + p3) ; //now determine R/B at grid points using interpolated colour differences and interpolated G value at grid point if (fabsf(grbdiffold) > fabsf(grbdiffint) ) { - rgb[c][indx] = rgb[1][indx] - grbdiffint; + rgb[c][indx >> 1] = rgb[1][indx] - grbdiffint; } } //if colour difference interpolation overshot the correction, just desaturate if (grbdiffold * grbdiffint < 0) { - rgb[c][indx] = rgb[1][indx] - 0.5f * (grbdiffold + grbdiffint); + rgb[c][indx >> 1] = rgb[1][indx] - 0.5f * (grbdiffold + grbdiffint); } } + } // copy CA corrected results to temporary image matrix for (int rr = border; rr < rr1 - border; rr++) { int c = FC(rr + top, left + border + (FC(rr + top, 2) & 1)); - - for (int row = rr + top, cc = border + (FC(rr, 2) & 1), indx = (row * width + cc + left) >> 1; cc < cc1 - border; cc += 2, indx++) { - RawDataTmp[indx] = 65535.0f * rgb[c][(rr) * ts + cc]; + int row = rr + top; + int cc = border + (FC(rr, 2) & 1); + int indx = (row * width + cc + left) >> 1; + int indx1 = (rr * ts + cc) >> 1; +#ifdef __SSE2__ + for (; indx < (row * width + cc1 - border - 7 + left) >> 1; indx+=4, indx1 += 4) { + STVFU(RawDataTmp[indx], c65535v * LVFU(rgb[c][indx1])); + } +#endif + for (; indx < (row * width + cc1 - border + left) >> 1; indx++, indx1++) { + RawDataTmp[indx] = 65535.f * rgb[c][indx1]; } } @@ -993,17 +1137,23 @@ void RawImageSource::CA_correct_RT(const bool autoCA, const double cared, const // copy temporary image matrix back to image matrix #pragma omp for - for(int row = 0; row < height; row++) - for(int col = 0 + (FC(row, 0) & 1), indx = (row * width + col) >> 1; col < width; col += 2, indx++) { + for(int row = 0; row < height; row++) { + int col = FC(row, 0) & 1; + int indx = (row * width + col) >> 1; +#ifdef __SSE2__ + for(; col < width - 7; col += 8, indx += 4) { + STC2VFU(rawData[row][col], LVFU(RawDataTmp[indx])); + } +#endif + for(; col < width; col += 2, indx++) { rawData[row][col] = RawDataTmp[indx]; } + } } // clean up free(buffer); - - } free(Gtmp); diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt index 8e8c08fd3..c8904703d 100644 --- a/rtengine/CMakeLists.txt +++ b/rtengine/CMakeLists.txt @@ -9,6 +9,7 @@ include_directories(${EXTRA_INCDIR} ${GTK_INCLUDE_DIRS} ${IPTCDATA_INCLUDE_DIRS} ${LCMS_INCLUDE_DIRS} + ${LENSFUN_INCLUDE_DIRS} ) link_directories("${PROJECT_SOURCE_DIR}/rtexif" @@ -21,6 +22,7 @@ link_directories("${PROJECT_SOURCE_DIR}/rtexif" ${GTHREAD_LIBRARY_DIRS} ${IPTCDATA_LIBRARY_DIRS} ${LCMS_LIBRARY_DIRS} + ${LENSFUN_LIBRARY_DIRS} ) set(CAMCONSTSFILE "camconst.json") @@ -71,6 +73,7 @@ set(RTENGINESOURCEFILES imageio.cc improccoordinator.cc improcfun.cc + impulse_denoise.cc init.cc iplab2rgb.cc ipresize.cc @@ -111,8 +114,15 @@ set(RTENGINESOURCEFILES spot.cc stdimagesource.cc utils.cc + rtlensfun.cc + tmo_fattal02.cc ) +if(LENSFUN_HAS_LOAD_DIRECTORY) + set_source_files_properties(rtlensfun.cc PROPERTIES COMPILE_DEFINITIONS RT_LENSFUN_HAS_LOAD_DIRECTORY) +endif() + + if(NOT WITH_SYSTEM_KLT) set(RTENGINESOURCEFILES ${RTENGINESOURCEFILES} klt/convolve.cc @@ -155,6 +165,7 @@ target_link_libraries(rtengine rtexif ${PNG_LIBRARIES} ${TIFF_LIBRARIES} ${ZLIB_LIBRARIES} + ${LENSFUN_LIBRARIES} ) install(FILES ${CAMCONSTSFILE} DESTINATION "${DATADIR}" PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ) diff --git a/rtengine/EdgePreservingDecomposition.cc b/rtengine/EdgePreservingDecomposition.cc index 1424af1b3..1c2d0219f 100644 --- a/rtengine/EdgePreservingDecomposition.cc +++ b/rtengine/EdgePreservingDecomposition.cc @@ -6,7 +6,6 @@ #endif #include "sleef.c" #include "opthelper.h" -#define pow_F(a,b) (xexpf(b*xlogf(a))) #define DIAGONALS 5 #define DIAGONALSP1 6 diff --git a/rtengine/FTblockDN.cc b/rtengine/FTblockDN.cc index 50b178388..0634deedd 100644 --- a/rtengine/FTblockDN.cc +++ b/rtengine/FTblockDN.cc @@ -71,9 +71,16 @@ namespace rtengine extern const Settings* settings; +extern MyMutex *fftwMutex; -void ImProcFunctions::Median_Denoise(float **src, float **dst, const int width, const int height, const Median medianType, const int iterations, const int numThreads, float **buffer) + +namespace { + +template +void do_median_denoise(float **src, float **dst, float upperBound, const int width, const int height, const ImProcFunctions::Median medianType, const int iterations, const int numThreads, float **buffer) { + typedef ImProcFunctions::Median Median; + int border = 1; switch (medianType) { @@ -110,7 +117,7 @@ void ImProcFunctions::Median_Denoise(float **src, float **dst, const int width, // we need a buffer if src == dst or if (src != dst && iterations > 1) if (src == dst || iterations > 1) { - if (buffer == nullptr) { // we didn't get a buufer => create one + if (buffer == nullptr) { // we didn't get a buffer => create one allocBuffer = new float*[height]; for (int i = 0; i < height; ++i) { @@ -154,13 +161,17 @@ void ImProcFunctions::Median_Denoise(float **src, float **dst, const int width, switch (medianType) { case Median::TYPE_3X3_SOFT: { for (; j < width - border; ++j) { - medianOut[i][j] = median( - medianIn[i - 1][j], - medianIn[i][j - 1], - medianIn[i][j], - medianIn[i][j + 1], - medianIn[i + 1][j] - ); + if (!useUpperBound || medianIn[i][j] <= upperBound) { + medianOut[i][j] = median( + medianIn[i - 1][j], + medianIn[i][j - 1], + medianIn[i][j], + medianIn[i][j + 1], + medianIn[i + 1][j] + ); + } else { + medianOut[i][j] = medianIn[i][j]; + } } break; @@ -168,17 +179,21 @@ void ImProcFunctions::Median_Denoise(float **src, float **dst, const int width, case Median::TYPE_3X3_STRONG: { for (; j < width - border; ++j) { - medianOut[i][j] = median( - medianIn[i - 1][j - 1], - medianIn[i - 1][j], - medianIn[i - 1][j + 1], - medianIn[i][j - 1], - medianIn[i][j], - medianIn[i][j + 1], - medianIn[i + 1][j - 1], - medianIn[i + 1][j], - medianIn[i + 1][j + 1] - ); + if (!useUpperBound || medianIn[i][j] <= upperBound) { + medianOut[i][j] = median( + medianIn[i - 1][j - 1], + medianIn[i - 1][j], + medianIn[i - 1][j + 1], + medianIn[i][j - 1], + medianIn[i][j], + medianIn[i][j + 1], + medianIn[i + 1][j - 1], + medianIn[i + 1][j], + medianIn[i + 1][j + 1] + ); + } else { + medianOut[i][j] = medianIn[i][j]; + } } break; @@ -186,21 +201,25 @@ void ImProcFunctions::Median_Denoise(float **src, float **dst, const int width, case Median::TYPE_5X5_SOFT: { for (; j < width - border; ++j) { - medianOut[i][j] = median( - medianIn[i - 2][j], - medianIn[i - 1][j - 1], - medianIn[i - 1][j], - medianIn[i - 1][j + 1], - medianIn[i][j - 2], - medianIn[i][j - 1], - medianIn[i][j], - medianIn[i][j + 1], - medianIn[i][j + 2], - medianIn[i + 1][j - 1], - medianIn[i + 1][j], - medianIn[i + 1][j + 1], - medianIn[i + 2][j] - ); + if (!useUpperBound || medianIn[i][j] <= upperBound) { + medianOut[i][j] = median( + medianIn[i - 2][j], + medianIn[i - 1][j - 1], + medianIn[i - 1][j], + medianIn[i - 1][j + 1], + medianIn[i][j - 2], + medianIn[i][j - 1], + medianIn[i][j], + medianIn[i][j + 1], + medianIn[i][j + 2], + medianIn[i + 1][j - 1], + medianIn[i + 1][j], + medianIn[i + 1][j + 1], + medianIn[i + 2][j] + ); + } else { + medianOut[i][j] = medianIn[i][j]; + } } break; @@ -208,8 +227,7 @@ void ImProcFunctions::Median_Denoise(float **src, float **dst, const int width, case Median::TYPE_5X5_STRONG: { #ifdef __SSE2__ - - for (; j < width - border - 3; j += 4) { + for (; !useUpperBound && j < width - border - 3; j += 4) { STVFU( medianOut[i][j], median( @@ -243,35 +261,38 @@ void ImProcFunctions::Median_Denoise(float **src, float **dst, const int width, } #endif - for (; j < width - border; ++j) { - medianOut[i][j] = median( - medianIn[i - 2][j - 2], - medianIn[i - 2][j - 1], - medianIn[i - 2][j], - medianIn[i - 2][j + 1], - medianIn[i - 2][j + 2], - medianIn[i - 1][j - 2], - medianIn[i - 1][j - 1], - medianIn[i - 1][j], - medianIn[i - 1][j + 1], - medianIn[i - 1][j + 2], - medianIn[i][j - 2], - medianIn[i][j - 1], - medianIn[i][j], - medianIn[i][j + 1], - medianIn[i][j + 2], - medianIn[i + 1][j - 2], - medianIn[i + 1][j - 1], - medianIn[i + 1][j], - medianIn[i + 1][j + 1], - medianIn[i + 1][j + 2], - medianIn[i + 2][j - 2], - medianIn[i + 2][j - 1], - medianIn[i + 2][j], - medianIn[i + 2][j + 1], - medianIn[i + 2][j + 2] - ); + if (!useUpperBound || medianIn[i][j] <= upperBound) { + medianOut[i][j] = median( + medianIn[i - 2][j - 2], + medianIn[i - 2][j - 1], + medianIn[i - 2][j], + medianIn[i - 2][j + 1], + medianIn[i - 2][j + 2], + medianIn[i - 1][j - 2], + medianIn[i - 1][j - 1], + medianIn[i - 1][j], + medianIn[i - 1][j + 1], + medianIn[i - 1][j + 2], + medianIn[i][j - 2], + medianIn[i][j - 1], + medianIn[i][j], + medianIn[i][j + 1], + medianIn[i][j + 2], + medianIn[i + 1][j - 2], + medianIn[i + 1][j - 1], + medianIn[i + 1][j], + medianIn[i + 1][j + 1], + medianIn[i + 1][j + 2], + medianIn[i + 2][j - 2], + medianIn[i + 2][j - 1], + medianIn[i + 2][j], + medianIn[i + 2][j + 1], + medianIn[i + 2][j + 2] + ); + } else { + medianOut[i][j] = medianIn[i][j]; + } } break; @@ -281,7 +302,7 @@ void ImProcFunctions::Median_Denoise(float **src, float **dst, const int width, #ifdef __SSE2__ std::array vpp ALIGNED16; - for (; j < width - border - 3; j += 4) { + for (; !useUpperBound && j < width - border - 3; j += 4) { for (int kk = 0, ii = -border; ii <= border; ++ii) { for (int jj = -border; jj <= border; ++jj, ++kk) { vpp[kk] = LVFU(medianIn[i + ii][j + jj]); @@ -294,15 +315,19 @@ void ImProcFunctions::Median_Denoise(float **src, float **dst, const int width, #endif std::array pp; - + for (; j < width - border; ++j) { - for (int kk = 0, ii = -border; ii <= border; ++ii) { - for (int jj = -border; jj <= border; ++jj, ++kk) { - pp[kk] = medianIn[i + ii][j + jj]; + if (!useUpperBound || medianIn[i][j] <= upperBound) { + for (int kk = 0, ii = -border; ii <= border; ++ii) { + for (int jj = -border; jj <= border; ++jj, ++kk) { + pp[kk] = medianIn[i + ii][j + jj]; + } } + + medianOut[i][j] = median(pp); + } else { + medianOut[i][j] = medianIn[i][j]; } - - medianOut[i][j] = median(pp); } break; @@ -312,7 +337,7 @@ void ImProcFunctions::Median_Denoise(float **src, float **dst, const int width, #ifdef __SSE2__ std::array vpp ALIGNED16; - for (; j < width - border - 3; j += 4) { + for (; !useUpperBound && j < width - border - 3; j += 4) { for (int kk = 0, ii = -border; ii <= border; ++ii) { for (int jj = -border; jj <= border; ++jj, ++kk) { vpp[kk] = LVFU(medianIn[i + ii][j + jj]); @@ -325,15 +350,19 @@ void ImProcFunctions::Median_Denoise(float **src, float **dst, const int width, #endif std::array pp; - + for (; j < width - border; ++j) { - for (int kk = 0, ii = -border; ii <= border; ++ii) { - for (int jj = -border; jj <= border; ++jj, ++kk) { - pp[kk] = medianIn[i + ii][j + jj]; + if (!useUpperBound || medianIn[i][j] <= upperBound) { + for (int kk = 0, ii = -border; ii <= border; ++ii) { + for (int jj = -border; jj <= border; ++jj, ++kk) { + pp[kk] = medianIn[i + ii][j + jj]; + } } + + medianOut[i][j] = median(pp); + } else { + medianOut[i][j] = medianIn[i][j]; } - - medianOut[i][j] = median(pp); } for (; j < width; ++j) { @@ -364,9 +393,8 @@ void ImProcFunctions::Median_Denoise(float **src, float **dst, const int width, #ifdef _OPENMP #pragma omp parallel for num_threads(numThreads) if (numThreads>1) #endif - - for (int i = border; i < height - border; ++i) { - for (int j = border; j < width - border; ++j) { + for (int i = 0; i < height; ++i) { + for (int j = 0; j < width; ++j) { dst[i][j] = medianOut[i][j]; } } @@ -381,6 +409,21 @@ void ImProcFunctions::Median_Denoise(float **src, float **dst, const int width, } } +} // namespace + + +void ImProcFunctions::Median_Denoise(float **src, float **dst, const int width, const int height, const Median medianType, const int iterations, const int numThreads, float **buffer) +{ + do_median_denoise(src, dst, 0.f, width, height, medianType, iterations, numThreads, buffer); +} + + +void ImProcFunctions::Median_Denoise(float **src, float **dst, float upperBound, const int width, const int height, const Median medianType, const int iterations, const int numThreads, float **buffer) +{ + do_median_denoise(src, dst, upperBound, width, height, medianType, iterations, numThreads, buffer); +} + + void ImProcFunctions::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) { @@ -424,7 +467,7 @@ void ImProcFunctions::Tile_calc(int tilesize, int overlap, int kall, int imwidth int denoiseNestedLevels = 1; enum nrquality {QUALITY_STANDARD, QUALITY_HIGH}; -SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagefloat * dst, Imagefloat * calclum, float * ch_M, float *max_r, float *max_b, bool isRAW, const procparams::DirPyrDenoiseParams & dnparams, const double expcomp, const NoiseCurve & noiseLCurve, const NoiseCurve & noiseCCurve, float &chaut, float &redaut, float &blueaut, float &maxredaut, float &maxblueaut, float &nresi, float &highresi) +SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagefloat * dst, Imagefloat * calclum, float * ch_M, float *max_r, float *max_b, bool isRAW, const procparams::DirPyrDenoiseParams & dnparams, const double expcomp, const NoiseCurve & noiseLCurve, const NoiseCurve & noiseCCurve, float &nresi, float &highresi) { //#ifdef _DEBUG MyTime t1e, t2e; @@ -445,8 +488,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef return; } - static MyMutex FftwMutex; - MyMutex::MyLock lock(FftwMutex); + MyMutex::MyLock lock(*fftwMutex); const nrquality nrQuality = (dnparams.smethod == "shal") ? QUALITY_STANDARD : QUALITY_HIGH;//shrink method const float qhighFactor = (nrQuality == QUALITY_HIGH) ? 1.f / static_cast( settings->nrhigh) : 1.0f; @@ -2797,10 +2839,10 @@ SSEFUNCTION void ImProcFunctions::ShrinkAllAB(wavelet_decomposition &WaveletCoef } -SSEFUNCTION void ImProcFunctions::ShrinkAll_info(float ** WavCoeffs_a, float ** WavCoeffs_b, int level, - int W_ab, int H_ab, int skip_ab, float **noisevarlum, float **noisevarchrom, float **noisevarhue, int width, int height, float noisevar_abr, float noisevar_abb, LabImage * noi, float &chaut, int &Nb, float &redaut, float &blueaut, - float &maxredaut, float &maxblueaut, float &minredaut, float &minblueaut, bool autoch, 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, bool multiThread) +SSEFUNCTION void ImProcFunctions::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) { //simple wavelet shrinkage @@ -2916,8 +2958,8 @@ SSEFUNCTION void ImProcFunctions::ShrinkAll_info(float ** WavCoeffs_a, float ** void ImProcFunctions::WaveletDenoiseAll_info(int levwav, wavelet_decomposition &WaveletCoeffs_a, - wavelet_decomposition &WaveletCoeffs_b, float **noisevarlum, float **noisevarchrom, float **noisevarhue, int width, int height, float noisevar_abr, float noisevar_abb, LabImage * noi, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float &maxblueaut, float &minredaut, float &minblueaut, int schoice, bool autoch, - 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 multiThread) + 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) { int maxlvl = levwav; @@ -2927,14 +2969,12 @@ void ImProcFunctions::WaveletDenoiseAll_info(int levwav, wavelet_decomposition & int Wlvl_ab = WaveletCoeffs_a.level_W(lvl); int Hlvl_ab = WaveletCoeffs_a.level_H(lvl); - int skip_ab = WaveletCoeffs_a.level_stride(lvl); - float ** WavCoeffs_a = WaveletCoeffs_a.level_coeffs(lvl); float ** WavCoeffs_b = WaveletCoeffs_b.level_coeffs(lvl); - ShrinkAll_info(WavCoeffs_a, WavCoeffs_b, lvl, Wlvl_ab, Hlvl_ab, - skip_ab, noisevarlum, noisevarchrom, noisevarhue, width, height, noisevar_abr, noisevar_abb, noi, chaut, Nb, redaut, blueaut, maxredaut, maxblueaut, minredaut, minblueaut, - autoch, schoice, lvl, chromina, sigma, lumema, sigma_L, redyel, skinc, nsknc, maxchred, maxchblue, minchred, minchblue, nb, chau, chred, chblue, denoiseMethodRgb, multiThread); + ShrinkAll_info(WavCoeffs_a, WavCoeffs_b, Wlvl_ab, Hlvl_ab, + noisevarlum, noisevarchrom, noisevarhue, chaut, Nb, redaut, blueaut, maxredaut, maxblueaut, minredaut, minblueaut, + schoice, lvl, chromina, sigma, lumema, sigma_L, redyel, skinc, nsknc, maxchred, maxchblue, minchred, minchblue, nb, chau, chred, chblue, denoiseMethodRgb); } } @@ -3235,9 +3275,6 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat noisevarhue[i] = new float[(width + 1) / 2]; } - // init luma noisevarL - float noisevarab_b, noisevarab_r; - float realred, realblue; float interm_med = static_cast( dnparams.chroma) / 10.0; float intermred, intermblue; @@ -3266,7 +3303,6 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat realblue = 0.001f; } - //TODO: implement using AlignedBufferMP //fill tile from image; convert RGB to "luma/chroma" if (isRAW) {//image is raw; use channel differences for chroma channels @@ -3467,8 +3503,6 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat //and whether to subsample the image after wavelet filtering. Subsampling is coded as //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. - noisevarab_r = SQR(realred) + 0.01f; - noisevarab_b = SQR(realblue) + 0.01f; wavelet_decomposition* adecomp; wavelet_decomposition* bdecomp; @@ -3497,8 +3531,6 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat bdecomp = new wavelet_decomposition (labdn->data + 2 * datalen, labdn->W, labdn->H, levwav, 1); } } - const bool autoch = (settings->leveldnautsimpl == 1 && (dnparams.Cmethod == "AUT" || dnparams.Cmethod == "PRE")) || (settings->leveldnautsimpl == 0 && (dnparams.C2method == "AUTO" || dnparams.C2method == "PREV")); - if (comptlevel == 0) { WaveletDenoiseAll_info( @@ -3508,11 +3540,6 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat noisevarlum, noisevarchrom, noisevarhue, - width, - height, - noisevarab_r, - noisevarab_b, - labdn, chaut, Nb, redaut, @@ -3522,7 +3549,6 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat minredaut, minblueaut, schoice, - autoch, chromina, sigma, lumema, @@ -3538,8 +3564,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat chau, chred, chblue, - denoiseMethodRgb, - multiThread + denoiseMethodRgb ); // Enhance mode } diff --git a/rtengine/PF_correct_RT.cc b/rtengine/PF_correct_RT.cc index 6e1fe75d6..a31c78767 100644 --- a/rtengine/PF_correct_RT.cc +++ b/rtengine/PF_correct_RT.cc @@ -655,7 +655,7 @@ SSEFUNCTION void ImProcFunctions::PF_correct_RTcam(CieImage * src, CieImage * ds free(fringe); } -SSEFUNCTION void ImProcFunctions::Badpixelscam(CieImage * src, CieImage * dst, double radius, int thresh, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom, int hotbad) +SSEFUNCTION void ImProcFunctions::Badpixelscam(CieImage * src, CieImage * dst, double radius, int thresh, int mode, float skinprot, float chrom, int hotbad) { const int halfwin = ceil(2 * radius) + 1; MyTime t1, t2; @@ -1263,7 +1263,7 @@ SSEFUNCTION void ImProcFunctions::Badpixelscam(CieImage * src, CieImage * dst, d } -SSEFUNCTION void ImProcFunctions::BadpixelsLab(LabImage * src, LabImage * dst, double radius, int thresh, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom) +SSEFUNCTION void ImProcFunctions::BadpixelsLab(LabImage * src, LabImage * dst, double radius, int thresh, int mode, float skinprot, float chrom) { const int halfwin = ceil(2 * radius) + 1; MyTime t1, t2; diff --git a/rtengine/alignedbuffer.h b/rtengine/alignedbuffer.h index 44fd43e81..dd9d7b278 100644 --- a/rtengine/alignedbuffer.h +++ b/rtengine/alignedbuffer.h @@ -18,12 +18,8 @@ */ #ifndef _ALIGNEDBUFFER_ #define _ALIGNEDBUFFER_ -#include #include -#include #include -#include -#include "../rtgui/threadutils.h" // Aligned buffer that should be faster template class AlignedBuffer @@ -111,7 +107,6 @@ public: } if (real) { - //data = (T*)( (uintptr_t)real + (alignment-((uintptr_t)real)%alignment) ); data = (T*)( ( uintptr_t(real) + uintptr_t(alignment - 1)) / alignment * alignment); inUse = true; } else { @@ -142,51 +137,4 @@ public: } }; -// Multi processor version, use with OpenMP -template class AlignedBufferMP -{ -private: - MyMutex mtx; - std::vector*> buffers; - size_t size; - -public: - explicit AlignedBufferMP(size_t sizeP) - { - size = sizeP; - } - - ~AlignedBufferMP() - { - for (size_t i = 0; i < buffers.size(); i++) { - delete buffers[i]; - } - } - - AlignedBuffer* acquire() - { - MyMutex::MyLock lock(mtx); - - // Find available buffer - for (size_t i = 0; i < buffers.size(); i++) { - if (!buffers[i]->inUse) { - buffers[i]->inUse = true; - return buffers[i]; - } - } - - // Add new buffer if nothing is free - AlignedBuffer* buffer = new AlignedBuffer(size); - buffers.push_back(buffer); - - return buffer; - } - - void release(AlignedBuffer* buffer) - { - MyMutex::MyLock lock(mtx); - - buffer->inUse = false; - } -}; #endif diff --git a/rtengine/boxblur.h b/rtengine/boxblur.h index 0fa31fc2a..5475e8ffc 100644 --- a/rtengine/boxblur.h +++ b/rtengine/boxblur.h @@ -34,8 +34,6 @@ namespace rtengine template void boxblur (T** src, A** dst, int radx, int rady, int W, int H) { - - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //box blur image; box range = (radx,rady) AlignedBuffer* buffer = new AlignedBuffer (W * H); @@ -125,8 +123,6 @@ template void boxblur (T** src, A** dst, int radx, int rady, i template SSEFUNCTION void boxblur (T** src, A** dst, T* buffer, int radx, int rady, int W, int H) { - - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //box blur image; box range = (radx,rady) float* temp = buffer; @@ -313,13 +309,8 @@ template SSEFUNCTION void boxblur (T** src, A** dst, T* buffer } -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - template SSEFUNCTION void boxblur (T* src, A* dst, A* buffer, int radx, int rady, int W, int H) { - - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //box blur image; box range = (radx,rady) i.e. box size is (2*radx+1)x(2*rady+1) float* temp = buffer; @@ -505,489 +496,6 @@ template SSEFUNCTION void boxblur (T* src, A* dst, A* buffer, } -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - -template void boxvar (T* src, T* dst, int radx, int rady, int W, int H) -{ - - AlignedBuffer buffer1(W * H); - AlignedBuffer buffer2(W * H); - float* tempave = buffer1.data; - float* tempsqave = buffer2.data; - - AlignedBufferMP buffer3(H); - - //float image_ave = 0; - - //box blur image channel; box size = 2*box+1 - //horizontal blur -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int row = 0; row < H; row++) { - int len = radx + 1; - tempave[row * W + 0] = src[row * W + 0] / len; - tempsqave[row * W + 0] = SQR(src[row * W + 0]) / len; - - for (int j = 1; j <= radx; j++) { - tempave[row * W + 0] += src[row * W + j] / len; - tempsqave[row * W + 0] += SQR(src[row * W + j]) / len; - } - - for (int col = 1; col <= radx; col++) { - tempave[row * W + col] = (tempave[row * W + col - 1] * len + src[row * W + col + radx]) / (len + 1); - tempsqave[row * W + col] = (tempsqave[row * W + col - 1] * len + SQR(src[row * W + col + radx])) / (len + 1); - len ++; - } - - for (int col = radx + 1; col < W - radx; col++) { - tempave[row * W + col] = tempave[row * W + col - 1] + (src[row * W + col + radx] - src[row * W + col - radx - 1]) / len; - tempsqave[row * W + col] = tempsqave[row * W + col - 1] + (SQR(src[row * W + col + radx]) - SQR(src[row * W + col - radx - 1])) / len; - } - - for (int col = W - radx; col < W; col++) { - tempave[row * W + col] = (tempave[row * W + col - 1] * len - src[row * W + col - radx - 1]) / (len - 1); - tempsqave[row * W + col] = (tempsqave[row * W + col - 1] * len - SQR(src[row * W + col - radx - 1])) / (len - 1); - len --; - } - } - - //vertical blur -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int col = 0; col < W; col++) { - AlignedBuffer* pBuf3 = buffer3.acquire(); - T* tempave2 = (T*)pBuf3->data; - - int len = rady + 1; - tempave2[0] = tempave[0 * W + col] / len; - dst[0 * W + col] = tempsqave[0 * W + col] / len; - - for (int i = 1; i <= rady; i++) { - tempave2[0] += tempave[i * W + col] / len; - dst[0 * W + col] += tempsqave[i * W + col] / len; - } - - for (int row = 1; row <= rady; row++) { - tempave2[row] = (tempave2[(row - 1)] * len + tempave[(row + rady) * W + col]) / (len + 1); - dst[row * W + col] = (dst[(row - 1) * W + col] * len + tempsqave[(row + rady) * W + col]) / (len + 1); - len ++; - } - - for (int row = rady + 1; row < H - rady; row++) { - tempave2[row] = tempave2[(row - 1)] + (tempave[(row + rady) * W + col] - tempave[(row - rady - 1) * W + col]) / len; - dst[row * W + col] = dst[(row - 1) * W + col] + (tempsqave[(row + rady) * W + col] - tempsqave[(row - rady - 1) * W + col]) / len; - } - - for (int row = H - rady; row < H; row++) { - tempave2[row] = (tempave2[(row - 1)] * len - tempave[(row - rady - 1) * W + col]) / (len - 1); - dst[row * W + col] = (dst[(row - 1) * W + col] * len - tempsqave[(row - rady - 1) * W + col]) / (len - 1); - len --; - } - - //now finish off - for (int row = 0; row < H; row++) { - dst[row * W + col] = fabs(dst[row * W + col] - SQR(tempave2[row])); - //image_ave += src[row*W+col]; - } - - buffer3.release(pBuf3); - } - - //image_ave /= (W*H); -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - -template void boxdev (T* src, T* dst, int radx, int rady, int W, int H) -{ - - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - //box blur image; box range = (radx,rady) i.e. box size is (2*radx+1)x(2*rady+1) - - AlignedBuffer* buffer1 = new AlignedBuffer (W * H); - float* temp = buffer1->data; - - AlignedBuffer* buffer2 = new AlignedBuffer (W * H); - float* tempave = buffer2->data; - - if (radx == 0) { -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int row = 0; row < H; row++) - for (int col = 0; col < W; col++) { - temp[row * W + col] = src[row * W + col]; - } - } else { - //horizontal blur -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int row = 0; row < H; row++) { - int len = radx + 1; - temp[row * W + 0] = (float)src[row * W + 0] / len; - - for (int j = 1; j <= radx; j++) { - temp[row * W + 0] += (float)src[row * W + j] / len; - } - - for (int col = 1; col <= radx; col++) { - temp[row * W + col] = (temp[row * W + col - 1] * len + src[row * W + col + radx]) / (len + 1); - len ++; - } - - for (int col = radx + 1; col < W - radx; col++) { - temp[row * W + col] = temp[row * W + col - 1] + ((float)(src[row * W + col + radx] - src[row * W + col - radx - 1])) / len; - } - - for (int col = W - radx; col < W; col++) { - temp[row * W + col] = (temp[row * W + col - 1] * len - src[row * W + col - radx - 1]) / (len - 1); - len --; - } - } - } - - if (rady == 0) { -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int row = 0; row < H; row++) { - for (int col = 0; col < W; col++) { - tempave[row * W + col] = temp[row * W + col]; - } - } - } else { - //vertical blur -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int col = 0; col < W; col++) { - int len = rady + 1; - tempave[0 * W + col] = temp[0 * W + col] / len; - - for (int i = 1; i <= rady; i++) { - tempave[0 * W + col] += temp[i * W + col] / len; - } - - for (int row = 1; row <= rady; row++) { - tempave[row * W + col] = (tempave[(row - 1) * W + col] * len + temp[(row + rady) * W + col]) / (len + 1); - len ++; - } - - for (int row = rady + 1; row < H - rady; row++) { - tempave[row * W + col] = tempave[(row - 1) * W + col] + (temp[(row + rady) * W + col] - temp[(row - rady - 1) * W + col]) / len; - } - - for (int row = H - rady; row < H; row++) { - tempave[row * W + col] = (tempave[(row - 1) * W + col] * len - temp[(row - rady - 1) * W + col]) / (len - 1); - len --; - } - } - } - - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - //box blur absolute deviation - - - if (radx == 0) { -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int row = 0; row < H; row++) - for (int col = 0; col < W; col++) { - temp[row * W + col] = fabs(src[row * W + col] - tempave[row * W + col]); - } - } else { - //horizontal blur -//OpenMP here -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int row = 0; row < H; row++) { - int len = radx + 1; - temp[row * W + 0] = fabs(src[row * W + 0] - tempave[row * W + 0]) / len; - - for (int j = 1; j <= radx; j++) { - temp[row * W + 0] += fabs(src[row * W + j] - tempave[row * W + j]) / len; - } - - for (int col = 1; col <= radx; col++) { - temp[row * W + col] = (temp[row * W + col - 1] * len + fabs(src[row * W + col + radx] - tempave[row * W + col + radx])) / (len + 1); - len ++; - } - - for (int col = radx + 1; col < W - radx; col++) { - temp[row * W + col] = temp[row * W + col - 1] + (fabs(src[row * W + col + radx] - tempave[row * W + col + radx]) - \ - fabs(src[row * W + col - radx - 1] - tempave[row * W + col - radx - 1])) / len; - } - - for (int col = W - radx; col < W; col++) { - temp[row * W + col] = (temp[row * W + col - 1] * len - fabs(src[row * W + col - radx - 1] - tempave[row * W + col - radx - 1])) / (len - 1); - len --; - } - } - } - - if (rady == 0) { -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int row = 0; row < H; row++) - for (int col = 0; col < W; col++) { - dst[row * W + col] = temp[row * W + col]; - } - } else { - //vertical blur -//OpenMP here -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int col = 0; col < W; col++) { - int len = rady + 1; - dst[0 * W + col] = temp[0 * W + col] / len; - - for (int i = 1; i <= rady; i++) { - dst[0 * W + col] += temp[i * W + col] / len; - } - - for (int row = 1; row <= rady; row++) { - dst[row * W + col] = (dst[(row - 1) * W + col] * len + temp[(row + rady) * W + col]) / (len + 1); - len ++; - } - - for (int row = rady + 1; row < H - rady; row++) { - dst[row * W + col] = dst[(row - 1) * W + col] + (temp[(row + rady) * W + col] - temp[(row - rady - 1) * W + col]) / len; - } - - for (int row = H - rady; row < H; row++) { - dst[row * W + col] = (dst[(row - 1) * W + col] * len - temp[(row - rady - 1) * W + col]) / (len - 1); - len --; - } - } - } - - delete buffer1; - delete buffer2; - -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - -template void boxsqblur (T* src, A* dst, int radx, int rady, int W, int H) -{ - - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - //box blur image; box range = (radx,rady) i.e. box size is (2*radx+1)x(2*rady+1) - - AlignedBuffer* buffer = new AlignedBuffer (W * H); - float* temp = buffer->data; - - if (radx == 0) { -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int row = 0; row < H; row++) - for (int col = 0; col < W; col++) { - temp[row * W + col] = SQR(src[row * W + col]); - } - } else { - //horizontal blur -//OpenMP here -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int row = 0; row < H; row++) { - int len = radx + 1; - temp[row * W + 0] = SQR((float)src[row * W + 0]) / len; - - for (int j = 1; j <= radx; j++) { - temp[row * W + 0] += SQR((float)src[row * W + j]) / len; - } - - for (int col = 1; col <= radx; col++) { - temp[row * W + col] = (temp[row * W + col - 1] * len + SQR(src[row * W + col + radx])) / (len + 1); - len ++; - } - - for (int col = radx + 1; col < W - radx; col++) { - temp[row * W + col] = temp[row * W + col - 1] + ((float)(SQR(src[row * W + col + radx]) - SQR(src[row * W + col - radx - 1]))) / len; - } - - for (int col = W - radx; col < W; col++) { - temp[row * W + col] = (temp[row * W + col - 1] * len - SQR(src[row * W + col - radx - 1])) / (len - 1); - len --; - } - } - } - - if (rady == 0) { -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int row = 0; row < H; row++) - for (int col = 0; col < W; col++) { - dst[row * W + col] = temp[row * W + col]; - } - } else { - //vertical blur -//OpenMP here -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int col = 0; col < W; col++) { - int len = rady + 1; - dst[0 * W + col] = temp[0 * W + col] / len; - - for (int i = 1; i <= rady; i++) { - dst[0 * W + col] += temp[i * W + col] / len; - } - - for (int row = 1; row <= rady; row++) { - dst[row * W + col] = (dst[(row - 1) * W + col] * len + temp[(row + rady) * W + col]) / (len + 1); - len ++; - } - - for (int row = rady + 1; row < H - rady; row++) { - dst[row * W + col] = dst[(row - 1) * W + col] + (temp[(row + rady) * W + col] - temp[(row - rady - 1) * W + col]) / len; - } - - for (int row = H - rady; row < H; row++) { - dst[row * W + col] = (dst[(row - 1) * W + col] * len - temp[(row - rady - 1) * W + col]) / (len - 1); - len --; - } - } - } - - delete buffer; - -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - -template void boxcorrelate (T* src, A* dst, int dx, int dy, int radx, int rady, int W, int H) -{ - - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - //box blur image; box range = (radx,rady) i.e. box size is (2*radx+1)x(2*rady+1) - - AlignedBuffer* buffer = new AlignedBuffer (W * H); - float* temp = buffer->data; - - if (radx == 0) { - for (int row = 0; row < H; row++) { - int rr = min(H - 1, max(0, row + dy)); - - for (int col = 0; col < W; col++) { - int cc = min(W - 1, max(0, col + dx)); - temp[row * W + col] = dy > 0 ? (src[row * W + col]) * (src[rr * W + cc]) : 0; - } - } - } else { - //horizontal blur - for (int row = 0; row < H; row++) { - int len = radx + 1; - int rr = min(H - 1, max(0, row + dy)); - int cc = min(W - 1, max(0, 0 + dx)); - temp[row * W + 0] = ((float)src[row * W + 0]) * (src[rr * W + cc]) / len; - - for (int j = 1; j <= radx; j++) { - int cc = min(W - 1, max(0, j + dx)); - temp[row * W + 0] += ((float)src[row * W + j]) * (src[rr * W + cc]) / len; - } - - for (int col = 1; col <= radx; col++) { - int cc = min(W - 1, max(0, col + dx + radx)); - temp[row * W + col] = (temp[row * W + col - 1] * len + (src[row * W + col + radx]) * (src[rr * W + cc])) / (len + 1); - len ++; - } - - for (int col = radx + 1; col < W - radx; col++) { - int cc = min(W - 1, max(0, col + dx + radx)); - int cc1 = min(W - 1, max(0, col + dx - radx - 1)); - temp[row * W + col] = temp[row * W + col - 1] + ((float)((src[row * W + col + radx]) * (src[rr * W + cc]) - - (src[row * W + col - radx - 1]) * (src[rr * W + cc1]))) / len; - } - - for (int col = W - radx; col < W; col++) { - int cc1 = min(W - 1, max(0, col + dx - radx - 1)); - temp[row * W + col] = (temp[row * W + col - 1] * len - (src[row * W + col - radx - 1]) * (src[rr * W + cc1])) / (len - 1); - len --; - } - } - } - - if (rady == 0) { -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int row = 0; row < H; row++) - for (int col = 0; col < W; col++) { - dst[row * W + col] = temp[row * W + col]; - } - } else { - //vertical blur -//OpenMP here -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int col = 0; col < W; col++) { - int len = rady + 1; - dst[0 * W + col] = temp[0 * W + col] / len; - - for (int i = 1; i <= rady; i++) { - dst[0 * W + col] += temp[i * W + col] / len; - } - - for (int row = 1; row <= rady; row++) { - dst[row * W + col] = (dst[(row - 1) * W + col] * len + temp[(row + rady) * W + col]) / (len + 1); - len ++; - } - - for (int row = rady + 1; row < H - rady; row++) { - dst[row * W + col] = dst[(row - 1) * W + col] + (temp[(row + rady) * W + col] - temp[(row - rady - 1) * W + col]) / len; - } - - for (int row = H - rady; row < H; row++) { - dst[row * W + col] = (dst[(row - 1) * W + col] * len - temp[(row - rady - 1) * W + col]) / (len - 1); - len --; - } - } - } - - delete buffer; - -} - - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - template SSEFUNCTION void boxabsblur (T* src, A* dst, int radx, int rady, int W, int H, float * temp) { @@ -1131,7 +639,5 @@ template SSEFUNCTION void boxabsblur (T* src, A* dst, int radx } -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - } #endif /* _BOXBLUR_H_ */ diff --git a/rtengine/cJSON.c b/rtengine/cJSON.c index 31c43dd2e..8e9cdcccf 100644 --- a/rtengine/cJSON.c +++ b/rtengine/cJSON.c @@ -191,12 +191,21 @@ static const char *parse_string(cJSON *item,const char *str) len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len; +#if defined( __GNUC__ ) && __GNUC__ >= 7// silence warning +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" +#endif + switch (len) { case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; case 1: *--ptr2 =(uc | firstByteMark[len]); } + +#if defined( __GNUC__ ) && __GNUC__ >= 7 +#pragma GCC diagnostic pop +#endif ptr2+=len; break; default: *ptr2++=*ptr; break; diff --git a/rtengine/camconst.cc b/rtengine/camconst.cc index 6b4a36c4b..469d18571 100644 --- a/rtengine/camconst.cc +++ b/rtengine/camconst.cc @@ -184,7 +184,7 @@ CameraConst::parseEntry(void *cJSON_, const char *make_model) js = (cJSON *)cJSON_; CameraConst *cc = new CameraConst; - cc->make_model = Glib::ustring(make_model); + cc->make_model = make_model; ji = cJSON_GetObjectItem(js, "dcraw_matrix"); @@ -739,7 +739,7 @@ CameraConstantsStore::get(const char make[], const char model[]) key += " "; key += model; key = key.uppercase(); - std::map::iterator it; + std::map::iterator it; it = mCameraConstants.find(key); if (it == mCameraConstants.end()) { diff --git a/rtengine/camconst.h b/rtengine/camconst.h index 31b65f3e8..47c8d8bee 100644 --- a/rtengine/camconst.h +++ b/rtengine/camconst.h @@ -17,7 +17,7 @@ struct camera_const_levels { class CameraConst { private: - Glib::ustring make_model; + std::string make_model; short dcraw_matrix[12]; int raw_crop[4]; int raw_mask[8][4]; @@ -48,7 +48,7 @@ public: class CameraConstantsStore { private: - std::map mCameraConstants; + std::map mCameraConstants; CameraConstantsStore(); bool parse_camera_constants_file(Glib::ustring filename); diff --git a/rtengine/camconst.json b/rtengine/camconst.json index 137339ceb..5a3a18fd1 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -1244,6 +1244,13 @@ Camera constants: "ranges": { "white": 4050 } }, + { // Quality B + "make_model": "FUJIFILM X-A10", + "dcraw_matrix": [ 11540,-4999,-991,-2949,10963,2278,-382,1049,5605 ], // DNGv9.12 D65 + "raw_crop": [ 0, 0, 4912, 3278 ], // full raw 4912x3278, fuji official borders 10,11,9,8 + "ranges": { "white": 4050 } + }, + { // Quality B "make_model": [ "FUJIFILM X-T1", "FUJIFILM X-T10", "FUJIFILM X-E2" ], "dcraw_matrix": [ 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 ], // DNG D65 @@ -1501,6 +1508,38 @@ Camera constants: "ranges": { "white": 16300 } // WL values for 14-bit files, RT auto adapts it for 12-bit files. Typical WL at 16383 }, + { // Quality A, Samples by zorgtool at RT forums + "make_model": "Nikon D850", + "dcraw_matrix": [ 10405,-3755,-1270,-5461,13787,1793,-1040,2015,6785 ], // DNGv9.12.1 d65 + "ranges": { + "white": [ + { "iso": [ 64, 80, 100, 125, 160, 200, 250, 320 ], "levels": [ 16250, 16050, 16250 ] }, // R,B 16383 G1,G2 16145-16155 + { "iso": [ 400, 500, 640, 800, 1000, 1250, 1600, 2000, 2500 ], "levels": [ 16150, 15950, 16150 ] }, // G1,G2 16110-16145 + { "iso": [ 3200, 4000, 5000 ], "levels": 16000 }, // G1,G2 16120-16145 + { "iso": [ 6400, 8000, 10000 ], "levels": 15700 }, // G1,G2 16120-16145 + { "iso": [ 12800, 16000 ], "levels": 15400 }, // 16383 + { "iso": [ 20000, 25600 ], "levels": 15000 }, // 16383 + { "iso": [ 32000 ], "levels": 14500 }, // 16383 + { "iso": [ 40000 ], "levels": 14000 }, // 16383 + { "iso": [ 51200 ], "levels": 13500 }, // nominal 16383 + { "iso": [ 102400 ], "levels": 12000 } // nominal 16383 + ], + "white_max": 16383, + "aperture_scaling": [ + // need for more data to properly fill all scale factors + { "aperture": 1.4, "scale_factor": 1.050 }, // 37/35 + { "aperture": 1.6, "scale_factor": 1.040 }, // 68/65 + { "aperture": 1.8, "scale_factor": 1.030 }, // 65/63 + { "aperture": 2.0, "scale_factor": 1.000 }, // + { "aperture": 2.2, "scale_factor": 1.000 }, // + { "aperture": 2.5, "scale_factor": 1.000 }, // + { "aperture": 2.8, "scale_factor": 1.000 }, // + { "aperture": 3.2, "scale_factor": 1.000 }, // + { "aperture": 3.5, "scale_factor": 1.000 } // + ] + } + }, + { // Quality B "make_model": "Nikon D80", "dcraw_matrix": [ 8629,-2410,-883,-9055,16940,2171,-1490,1363,8520 ], // Dcraw.c d65 @@ -1535,8 +1574,8 @@ Camera constants: { // Quality B, 20Mp and 80Mp raw frames, "make_model": "OLYMPUS E-M1MarkII", - //"dcraw_matrix": [ 9422,-3258,-711,-2655,10898,2015,-512,1354,5512 ], // E-M5II dng_v9.5 D65 - "dcraw_matrix": [ 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 ], // beta, dng_v9.8 D65 + "dcraw_matrix": [ 9383,-3170,-763,-2457,10702,2020,-384,1236,5552 ], // dng_V9.10 D65 + //"dcraw_matrix": [ 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 ], // beta, dng_v9.8 D65 "raw_crop": [ 8, 8, -16, -8 ], // full raw 5240X3912, jpeg top12,left12,5184x3888, full hires 10400X7792, jpeg crop 8,8,10368x7776 "ranges": { "white": [ @@ -1555,7 +1594,7 @@ Camera constants: }, { // Quality B, crop correction - "make_model": [ "OLYMPUS E-M10", "OLYMPUS E-M10MarkII" ], + "make_model": [ "OLYMPUS E-M10", "OLYMPUS E-M10MarkII", "OLYMPUS E-M10 Mark III" ], "dcraw_matrix": [ 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 ], "raw_crop": [ 0, 0, 4624, 3472 ], // largest valid - full frame is 4640x3472 //"raw_crop": [ 4, 4, 4616, 3464 ], // olympus jpeg crop 8, 8, 4608, 3456 @@ -1604,6 +1643,13 @@ Camera constants: } }, + { // Quality B + "make_model": [ "Panasonic DC-FZ80", "Panasonic DC-FZ81", "Panasonic DC-FZ82", "Panasonic DC-FZ83" ], + "dcraw_matrix": [ 8550,-2908,-842,-3195,11529,1881,-338,1603,4631 ], // DNGv9.10.1 D65 + "raw_crop": [ 0, 6, -8, -2 ], // fullraw4/3 5040x3688 official 8,8,4904,3680 = 4896X3672. Dcraw 0,0,4912,3688 RT's frame gets smaller than dcraw but works better with auto distortion + "ranges": { "black": 15, "white": 4050 } // 15 is BL offset. dcraw/RT read the base offset from Exif and calculates total BL = BLbase+BLoffset + }, + { // Quality A, replicated from rawimage.cc "make_model": "Panasonic DMC-FZ150", "dcraw_matrix": [ 10435,-3208,-72,-2293,10506,2067,-486,1725,4682 ], // RT, copy from custom dcp d55 @@ -1672,10 +1718,17 @@ Camera constants: { // Quality B "make_model": [ "Panasonic DMC-TZ70", "Panasonic DMC-TZ71", "Panasonic DMC-ZS50", "Panasonic DMC-ZS51" ], "dcraw_matrix": [ 8802,-3135,-789,-3151,11468,1904,-550,1745,4810 ], // DNG_V8.8 D65 - "raw_crop": [ 4, 4, -4, -4 ], // full raw 4/3 4144x3016 8,8,3008,4008 = 4000X3000. RT's frame gets smaller than dcraw but works better with auto distortion + "raw_crop": [ 0, 0, -4, -4 ], // full raw 4/3 4144x3016 8,8,3008,4008 = 4000X3000. RT's frame gets smaller than dcraw but works better with auto distortion "ranges": { "black": 14, "white": 4050 } // 12+1+1 is BL offset }, + { // Quality A, samples by Hombre + "make_model": [ "Panasonic DC-ZS70", "Panasonic DC-TZ90", "Panasonic DC-TZ91", "Panasonic DC-TZ92", "Panasonic DC-TZ93" ], + "dcraw_matrix": [ 9052,-3117,-883,-3045,11346,1927,-205,1520,4730 ], // DNG_V9.10.1 D65 + "raw_crop": [ 0, 6, -8, -2 ], // fullraw4/3 5264x3904 official 8,8,3896,5192 = 5184X3888. Dcraw 0,0,5200,3904 RT's frame gets smaller than dcraw but works better with auto distortion + "ranges": { "black": 16, "white": 4050 } // 12+3+1 is BL offset + }, + // Panasonic DMC-FZ150,G10,G1,G2,G3,G5,GF1,GF2,GF3 are included as overwrites of the same items of rawimage.cc to test the dcraw9.21 patch { // Quality A, Replicated from rawimage.cc @@ -2055,7 +2108,7 @@ Camera constants: "raw_crop": [ 92, 38, 5480, 3656 ] // jpeg 5472x3648 - full raw: 5600 x 3714 - Samsung's official crop: 96, 42, 5568, 3690 }, - { // Quality B, RT normally use the embedded data with DNGs but because various DNG use different color matrix adobe_coeff setting is used in dcraw.cc to always use the data from camconst.json for NX1 + { // Quality B, RT normally use the embedded data with DNGs but because various DNGs use different color matrix, adobe_coeff setting is used in dcraw.cc to always use the data from camconst.json for NX1 "make_model": [ "Samsung NX1", "Samsung NX500" ], "dcraw_matrix": [ 10686,-4042,-1052,-3595,13238,276,-464,1259,5931 ], // DNG_v8.7 D65 //"dcraw_matrix": [ 13298,-6099,-296,-5243,16153,-1235,-508,1220,7758 ], // DNG_v8.7 Standard Light A @@ -2227,13 +2280,13 @@ Camera constants: }, { // Quality B - "make_model": [ "Sony DSC-RX10M2", "Sony DSC-RX10M3" ], + "make_model": [ "Sony DSC-RX10M2", "Sony DSC-RX10M3", "Sony DSC-RX10M4" ], "dcraw_matrix": [ 6679,-1825,-745,-5047,13256,1953,-1580,2422,5183 ], // DNG_v9.6 D65 "ranges": { "black": 800, "white": 16300 } }, { // Quality C, No proper color data, beta samples, frame set to official jpeg, - "make_model": "XIAOYI M1", + "make_model": [ "XIAOYI M1", "YI TECHNOLOGY M1" ], "dcraw_matrix": [ 7158,-1911,-606,-3603,10669,2530,-659,1236,5530 ], // XIAO YI DNG D65 "raw_crop": [ 4, 3, 5192, 3896 ], // full raw 5200x3902, official jpeg 5184X3888 "ranges": { diff --git a/rtengine/ciecam02.cc b/rtengine/ciecam02.cc index 488093060..77c57048a 100644 --- a/rtengine/ciecam02.cc +++ b/rtengine/ciecam02.cc @@ -30,7 +30,6 @@ #undef CLIPD #define CLIPD(a) ((a)>0.0?((a)<1.0?(a):1.0):0.0) #define MAXR(a,b) ((a) > (b) ? (a) : (b)) -#define pow_F(a,b) (xexpf(b*xlogf(a))) namespace rtengine { @@ -178,6 +177,8 @@ void Ciecam02::curveJ (double br, double contr, int db, LUTf & outCurve, LUTu & for (int i = 0; i < (db * 32768); i++) { outCurve[i] = db * 32768.0 * dcurve[i]; } +// printf("double out500=%f out15000=%f\n", outCurve[500], outCurve[15000]); + } void Ciecam02::curveJfloat (float br, float contr, const LUTu & histogram, LUTf & outCurve) @@ -268,6 +269,8 @@ void Ciecam02::curveJfloat (float br, float contr, const LUTu & histogram, LUTf } outCurve *= 32767.f; + //printf("out500=%f out15000=%f\n", outCurve[500], outCurve[15000]); + //outCurve.dump("brig"); } /** @@ -776,7 +779,7 @@ void Ciecam02::initcam2float (float gamu, float yb, float pilotd, float f, float void Ciecam02::xyz2jchqms_ciecam02 ( double &J, double &C, double &h, double &Q, double &M, double &s, double &aw, double &fl, double &wh, double x, double y, double z, double xw, double yw, double zw, - double yb, double la, double f, double c, double nc, double pilotd, int gamu, double n, double nbb, double ncb, double pfl, double cz, double d) + double c, double nc, int gamu, double n, double nbb, double ncb, double pfl, double cz, double d) { double r, g, b; double rw, gw, bw; @@ -1036,8 +1039,8 @@ void Ciecam02::xyz2jch_ciecam02float ( float &J, float &C, float &h, float aw, f void Ciecam02::jch2xyz_ciecam02 ( double &x, double &y, double &z, double J, double C, double h, - double xw, double yw, double zw, double yb, double la, - double f, double c, double nc, int gamu, double n, double nbb, double ncb, double fl, double cz, double d, double aw ) + double xw, double yw, double zw, + double c, double nc, int gamu, double n, double nbb, double ncb, double fl, double cz, double d, double aw ) { double r, g, b; double rc, gc, bc; @@ -1071,7 +1074,7 @@ void Ciecam02::jch2xyz_ciecam02 ( double &x, double &y, double &z, double J, dou void Ciecam02::jch2xyz_ciecam02float ( float &x, float &y, float &z, float J, float C, float h, float xw, float yw, float zw, - float f, float c, float nc, int gamu, float pow1, float nbb, float ncb, float fl, float cz, float d, float aw) + float c, float nc, int gamu, float pow1, float nbb, float ncb, float fl, float cz, float d, float aw) { float r, g, b; float rc, gc, bc; @@ -1106,7 +1109,7 @@ void Ciecam02::jch2xyz_ciecam02float ( float &x, float &y, float &z, float J, fl #ifdef __SSE2__ void Ciecam02::jch2xyz_ciecam02float ( vfloat &x, vfloat &y, vfloat &z, vfloat J, vfloat C, vfloat h, vfloat xw, vfloat yw, vfloat zw, - vfloat f, vfloat nc, vfloat pow1, vfloat nbb, vfloat ncb, vfloat fl, vfloat d, vfloat aw, vfloat reccmcz) + vfloat nc, vfloat pow1, vfloat nbb, vfloat ncb, vfloat fl, vfloat d, vfloat aw, vfloat reccmcz) { vfloat r, g, b; vfloat rc, gc, bc; diff --git a/rtengine/ciecam02.h b/rtengine/ciecam02.h index 1e0f755c1..55d807b7e 100644 --- a/rtengine/ciecam02.h +++ b/rtengine/ciecam02.h @@ -82,19 +82,18 @@ public: static void jch2xyz_ciecam02 ( double &x, double &y, double &z, double J, double C, double h, double xw, double yw, double zw, - double yb, double la, - double f, double c, double nc, int gamu, double n, double nbb, double ncb, double fl, double cz, double d, double aw); + double c, double nc, int gamu, double n, double nbb, double ncb, double fl, double cz, double d, double aw); static void jch2xyz_ciecam02float ( float &x, float &y, float &z, float J, float C, float h, float xw, float yw, float zw, - float f, float c, float nc, int gamu, float n, float nbb, float ncb, float fl, float cz, float d, float aw ); + float c, float nc, int gamu, float n, float nbb, float ncb, float fl, float cz, float d, float aw ); #ifdef __SSE2__ static void jch2xyz_ciecam02float ( vfloat &x, vfloat &y, vfloat &z, vfloat J, vfloat C, vfloat h, vfloat xw, vfloat yw, vfloat zw, - vfloat f, vfloat nc, vfloat n, vfloat nbb, vfloat ncb, vfloat fl, vfloat d, vfloat aw, vfloat reccmcz ); + vfloat nc, vfloat n, vfloat nbb, vfloat ncb, vfloat fl, vfloat d, vfloat aw, vfloat reccmcz ); #endif /** * Forward transform from XYZ to CIECAM02 JCh. @@ -115,8 +114,7 @@ public: double &Q, double &M, double &s, double &aw, double &fl, double &wh, double x, double y, double z, double xw, double yw, double zw, - double yb, double la, - double f, double c, double nc, double pilotd, int gamu, double n, double nbb, double ncb, double pfl, double cz, double d ); + double c, double nc, int gamu, double n, double nbb, double ncb, double pfl, double cz, double d ); static void xyz2jch_ciecam02float ( float &J, float &C, float &h, float aw, float fl, diff --git a/rtengine/clutstore.cc b/rtengine/clutstore.cc index ba117a2fd..565db8faa 100644 --- a/rtengine/clutstore.cc +++ b/rtengine/clutstore.cc @@ -52,7 +52,7 @@ bool loadFile( rtengine::procparams::ColorManagementParams icm; icm.working = working_color_space; - img_src.getImage(curr_wb, TR_NONE, img_float.get(), pp, rtengine::procparams::ToneCurveParams(), icm, rtengine::procparams::RAWParams()); + img_src.getImage(curr_wb, TR_NONE, img_float.get(), pp, rtengine::procparams::ToneCurveParams(), rtengine::procparams::RAWParams()); if (!working_color_space.empty()) { img_src.convertColorSpace(img_float.get(), icm, curr_wb); @@ -305,7 +305,7 @@ rtengine::CLUTStore& rtengine::CLUTStore::getInstance() return instance; } -std::shared_ptr rtengine::CLUTStore::getClut(const Glib::ustring& filename) +std::shared_ptr rtengine::CLUTStore::getClut(const Glib::ustring& filename) const { std::shared_ptr result; diff --git a/rtengine/clutstore.h b/rtengine/clutstore.h index 5e4930fa1..a43526f78 100644 --- a/rtengine/clutstore.h +++ b/rtengine/clutstore.h @@ -57,14 +57,14 @@ class CLUTStore final : public: static CLUTStore& getInstance(); - std::shared_ptr getClut(const Glib::ustring& filename); + std::shared_ptr getClut(const Glib::ustring& filename) const; void clearCache(); private: CLUTStore(); - Cache> cache; + mutable Cache> cache; }; } diff --git a/rtengine/color.cc b/rtengine/color.cc index 0957ac71e..7964cc472 100644 --- a/rtengine/color.cc +++ b/rtengine/color.cc @@ -25,8 +25,6 @@ #include "opthelper.h" #include "iccstore.h" -#define pow_F(a,b) (xexpf(b*xlogf(a))) - using namespace std; namespace rtengine @@ -1526,9 +1524,9 @@ void Color::interpolateRGBColor (const float balance, const float r1, const floa void Color::interpolateRGBColor (float realL, float iplow, float iphigh, int algm, const float balance, int twoc, int metchrom, - bool chr, bool lum, float chromat, float luma, const float r1, const float g1, const float b1, + 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, - int toDo, const double xyz_rgb[3][3], const double rgb_xyz[3][3], float &ro, float &go, float &bo) + 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; @@ -1620,7 +1618,7 @@ void Color::interpolateRGBColor (float realL, float iplow, float iphigh, int alg Color::xyz2rgb(X, Y, Z, ro, go, bo, rgb_xyz);// ro go bo in gamut } -void Color::calcGamma (double pwr, double ts, int mode, int imax, GammaValues &gamma) +void Color::calcGamma (double pwr, double ts, int mode, GammaValues &gamma) { //from Dcraw (D.Coffin) int i; @@ -2604,7 +2602,7 @@ void Color::gamutLchonly (float2 sincosval, float &Lprov1, float &Chprov1, const * const double wip[3][3]: matrix for working profile * bool multiThread : parallelize the loop */ -SSEFUNCTION void Color::LabGamutMunsell(float *labL, float *laba, float *labb, const int N, bool corMunsell, bool lumaMuns, bool isHLEnabled, bool gamut, const double wip[3][3], bool multiThread ) +SSEFUNCTION void Color::LabGamutMunsell(float *labL, float *laba, float *labb, const int N, bool corMunsell, bool lumaMuns, bool isHLEnabled, bool gamut, const double wip[3][3]) { #ifdef _DEBUG MyTime t1e, t2e; diff --git a/rtengine/color.h b/rtengine/color.h index 5889095ca..59e189810 100644 --- a/rtengine/color.h +++ b/rtengine/color.h @@ -733,7 +733,7 @@ public: * @param go green channel of output color [0 ; 65535] (return value) * @param bo blue channel of output color [0 ; 65535] (return value) */ - static void interpolateRGBColor (float realL, float iplow, float iphigh, int algm, const float balance, int twoc, int metchrom, bool chr, bool lum, 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, int channels, const double xyz_rgb[3][3], const double rgb_xyz[3][3], float &ro, float &go, float &bo); + static void 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); /** @@ -898,7 +898,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, int imax, GammaValues &gamma); + static void calcGamma (double pwr, double ts, int mode, GammaValues &gamma); /** @@ -1310,7 +1310,7 @@ public: * @param wip matrix for working profile * @param multiThread whether to parallelize the loop or not */ - static void LabGamutMunsell (float *labL, float *laba, float *labb, const int N, bool corMunsell, bool lumaMuns, bool isHLEnabled, bool gamut, const double wip[3][3], bool multiThread ); + static void LabGamutMunsell (float *labL, float *laba, float *labb, const int N, bool corMunsell, bool lumaMuns, bool isHLEnabled, bool gamut, const double wip[3][3]); /* diff --git a/rtengine/colortemp.cc b/rtengine/colortemp.cc index ea90f2735..ab318aa73 100644 --- a/rtengine/colortemp.cc +++ b/rtengine/colortemp.cc @@ -24,11 +24,6 @@ #include "sleef.c" #include "settings.h" -#undef CLIPD -#define CLIPD(a) ((a)>0.0?((a)<1.0?(a):1.0):0.0) -#define CLIPQQ(a) ((a)>0?((a)<250?(a):250):0) -#define MAXR(a,b) ((a) > (b) ? (a) : (b)) - namespace rtengine { @@ -70,48 +65,22 @@ static const double cie_colour_match_jd[97][3] = {//350nm to 830nm 5 nm J.Desm {0.000001251141, 0.00000045181, 0.000000} }; -ColorTemp::ColorTemp (double t, double g, double e, const Glib::ustring &m) : temp(t), green(g), equal(e), method(m) +ColorTemp::ColorTemp (double t, double g, double e, const std::string &m) : temp(t), green(g), equal(e), method(m) { - clip (temp, green, equal); } void ColorTemp::clip (double &temp, double &green) { - - if (temp < MINTEMP) { - temp = MINTEMP; - } else if (temp > MAXTEMP) { - temp = MAXTEMP; - } - - if (green < MINGREEN) { - green = MINGREEN; - } else if (green > MAXGREEN) { - green = MAXGREEN; - } + temp = rtengine::LIM(temp, MINTEMP, MAXTEMP); + green = rtengine::LIM(green, MINGREEN, MAXGREEN); } void ColorTemp::clip (double &temp, double &green, double &equal) { - - if (temp < MINTEMP) { - temp = MINTEMP; - } else if (temp > MAXTEMP) { - temp = MAXTEMP; - } - - if (green < MINGREEN) { - green = MINGREEN; - } else if (green > MAXGREEN) { - green = MAXGREEN; - } - - if(equal < MINEQUAL) { - equal = MINEQUAL; - } else if(equal > MAXEQUAL) { - equal = MAXEQUAL; - } + temp = rtengine::LIM(temp, MINTEMP, MAXTEMP); + green = rtengine::LIM(green, MINGREEN, MAXGREEN); + equal = rtengine::LIM(equal, MINEQUAL, MAXEQUAL); } ColorTemp::ColorTemp (double mulr, double mulg, double mulb, double e) : equal(e), method("Custom") @@ -122,7 +91,7 @@ ColorTemp::ColorTemp (double mulr, double mulg, double mulb, double e) : equal(e void ColorTemp::mul2temp (const double rmul, const double gmul, const double bmul, const double equal, double& temp, double& green) const { - double maxtemp = double(MAXTEMP), mintemp = double(MINTEMP); + double maxtemp = MAXTEMP, mintemp = MINTEMP; double tmpr, tmpg, tmpb; temp = (maxtemp + mintemp) / 2; @@ -354,6 +323,37 @@ const double ColorTemp::Flash6500_spect[97] = { 55.72, 51.97, 54.72, 57.46, 58.89, 60.33 }; +const std::map ColorTemp::spectMap = { + {"Daylight", Daylight5300_spect}, + {"Cloudy", Cloudy6200_spect}, + {"Shade", Shade7600_spect}, + {"Tungsten", A2856_spect}, + {"Fluo F1", FluoF1_spect}, + {"Fluo F2", FluoF2_spect}, + {"Fluo F3", FluoF3_spect}, + {"Fluo F4", FluoF4_spect}, + {"Fluo F5", FluoF5_spect}, + {"Fluo F6", FluoF6_spect}, + {"Fluo F7", FluoF7_spect}, + {"Fluo F8", FluoF8_spect}, + {"Fluo F9", FluoF9_spect}, + {"Fluo F10", FluoF10_spect}, + {"Fluo F11", FluoF11_spect}, + {"Fluo F12", FluoF12_spect}, + {"HMI Lamp", HMI_spect}, + {"GTI Lamp", GTI_spect}, + {"JudgeIII Lamp", JudgeIII_spect}, + {"Solux Lamp 3500K", Solux3500_spect}, + {"Solux Lamp 4100K", Solux4100_spect}, + {"Solux Lamp 4700K", Solux4700_spect}, + {"NG Solux Lamp 4700K", NG_Solux4700_spect}, + {"LED LSI Lumelex 2040", NG_LEDLSI2040_spect}, + {"LED CRS SP12 WWMR16", NG_CRSSP12WWMR16_spect}, + {"Flash 5500K", Flash5500_spect}, + {"Flash 6000K", Flash6000_spect}, + {"Flash 6500K", Flash6500_spect} + }; + // Data for Color ==> CRI (Color Rendering Index and Palette // actually 20 color that must be good enough for CRI @@ -844,10 +844,7 @@ const double ColorTemp::ColabSky42_0_m24_spect[97] = { * Gunter Wyszecki and W. S. Stiles, John Wiley & Sons, 1982, pp. 227, 228. */ //adaptation to RT by J.Desmis -#include -/* LERP(a,b,c) = linear interpolation macro, is 'a' when c == 0.0 and 'b' when c == 1.0 */ -#define LERP(a,b,c) (((b) - (a)) * (c) + (a)) int ColorTemp::XYZtoCorColorTemp(double x0, double y0, double z0, double &temp) const { @@ -922,13 +919,13 @@ int ColorTemp::XYZtoCorColorTemp(double x0, double y0, double z0, double &temp) } if (i == 31) { - return(-1); /* bad XYZ input, color temp would be less than minimum of 1666.7 degrees, or too far towards blue */ + return -1; /* bad XYZ input, color temp would be less than minimum of 1666.7 degrees, or too far towards blue */ } di = di / sqrt(1.0 + uvt[i ].t * uvt[i ].t); dm = dm / sqrt(1.0 + uvt[i - 1].t * uvt[i - 1].t); p = dm / (dm - di); /* p = interpolation parameter, 0.0 : i-1, 1.0 : i */ - p = 1.0 / (LERP(rt[i - 1], rt[i], p)); + p = 1.0 / rtengine::intp(p, rt[i], rt[i - 1]); temp = p; return 0; /* success */ } @@ -1025,192 +1022,15 @@ void ColorTemp::cieCAT02(double Xw, double Yw, double Zw, double &CAM02BB00, dou } -void ColorTemp::temp2mulxyz (double tem, double gree, const std::string &method, double &Xxyz, double &Zxyz) +void ColorTemp::temp2mulxyz (double temp, const std::string &method, double &Xxyz, double &Zxyz) { - double xD, yD, x_D, y_D, interm; double x, y, z; - if (method == "Daylight" ) { - spectrum_to_xyz_preset(Daylight5300_spect, x, y, z); - } else if(method == "Cloudy" ) { - spectrum_to_xyz_preset(Cloudy6200_spect, x, y, z); - } else if(method == "Shade" ) { - spectrum_to_xyz_preset(Shade7600_spect, x, y, z); - } else if(method == "Tungsten" ) { - spectrum_to_xyz_preset(A2856_spect, x, y, z); - } else if(method == "Fluo F1" ) { - spectrum_to_xyz_preset(FluoF1_spect, x, y, z); - } else if(method == "Fluo F2" ) { - spectrum_to_xyz_preset(FluoF2_spect, x, y, z); - } else if(method == "Fluo F3" ) { - spectrum_to_xyz_preset(FluoF3_spect, x, y, z); - } else if(method == "Fluo F4" ) { - spectrum_to_xyz_preset(FluoF4_spect, x, y, z); - } else if(method == "Fluo F5" ) { - spectrum_to_xyz_preset(FluoF5_spect, x, y, z); - } else if(method == "Fluo F6" ) { - spectrum_to_xyz_preset(FluoF6_spect, x, y, z); - } else if(method == "Fluo F7" ) { - spectrum_to_xyz_preset(FluoF7_spect, x, y, z); - } else if(method == "Fluo F8" ) { - spectrum_to_xyz_preset(FluoF8_spect, x, y, z); - } else if(method == "Fluo F9" ) { - spectrum_to_xyz_preset(FluoF9_spect, x, y, z); - } else if(method == "Fluo F10" ) { - spectrum_to_xyz_preset(FluoF10_spect, x, y, z); - } else if(method == "Fluo F11" ) { - spectrum_to_xyz_preset(FluoF11_spect, x, y, z); - } else if(method == "Fluo F12" ) { - spectrum_to_xyz_preset(FluoF12_spect, x, y, z); - } else if(method == "HMI Lamp" ) { - spectrum_to_xyz_preset(HMI_spect, x, y, z); - } else if(method == "GTI Lamp" ) { - spectrum_to_xyz_preset(GTI_spect, x, y, z); - } else if(method == "JudgeIII Lamp" ) { - spectrum_to_xyz_preset(JudgeIII_spect, x, y, z); - } else if(method == "Solux Lamp 3500K" ) { - spectrum_to_xyz_preset(Solux3500_spect, x, y, z); - } else if(method == "Solux Lamp 4100K" ) { - spectrum_to_xyz_preset(Solux4100_spect, x, y, z); - } else if(method == "Solux Lamp 4700K" ) { - spectrum_to_xyz_preset(Solux4700_spect, x, y, z); - } else if(method == "NG Solux Lamp 4700K" ) { - spectrum_to_xyz_preset(NG_Solux4700_spect, x, y, z); - } else if(method == "LED LSI Lumelex 2040") { - spectrum_to_xyz_preset(NG_LEDLSI2040_spect, x, y, z); - } else if(method == "LED CRS SP12 WWMR16" ) { - spectrum_to_xyz_preset(NG_CRSSP12WWMR16_spect, x, y, z); - } else if(method == "Flash 5500K" ) { - spectrum_to_xyz_preset(Flash5500_spect, x, y, z); - } else if(method == "Flash 6000K" ) { - spectrum_to_xyz_preset(Flash6000_spect, x, y, z); - } else if(method == "Flash 6500K" ) { - spectrum_to_xyz_preset(Flash6500_spect, x, y, z); - } else { - // otherwise we use the Temp+Green generic solution - if (tem <= INITIALBLACKBODY) { - // if temperature is between 2000K and 4000K we use blackbody, because there will be no Daylight reference below 4000K... - // of course, the previous version of RT used the "magical" but wrong formula of U.Fuchs (Ufraw). - spectrum_to_xyz_blackbody(tem, x, y, z); - } else { - // from 4000K up to 25000K: using the D illuminant (daylight) which is standard - double m1, m2; - - if (tem <= 7000) { - x_D = -4.6070e9 / (tem * tem * tem) + 2.9678e6 / (tem * tem) + 0.09911e3 / tem + 0.244063; - } else if (tem <= 25000) { - x_D = -2.0064e9 / (tem * tem * tem) + 1.9018e6 / (tem * tem) + 0.24748e3 / tem + 0.237040; - } else /*if (tem > 25000)*/ { - x_D = -2.0064e9 / (tem * tem * tem) + 1.9018e6 / (tem * tem) + 0.24748e3 / tem + 0.237040 - ((tem - 25000) / 25000) * 0.025; //Jacques empirical adjustemnt for very high temp (underwater !) - } - - y_D = -3.0 * x_D * x_D + 2.87 * x_D - 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) - interm = (0.0241 + 0.2562 * x_D - 0.734 * y_D); - m1 = (-1.3515 - 1.7703 * x_D + 5.9114 * y_D) / interm; - m2 = (0.03 - 31.4424 * x_D + 30.0717 * y_D) / interm; - spectrum_to_xyz_daylight(m1, m2, x, y, z); - xD = x; - yD = y; - } - - } - - xD = x; - yD = y; - - double X = xD / yD; - double Z = (1.0 - xD - yD) / yD; - Xxyz = X; - Zxyz = Z; - //printf("Xxyz=%f Zxyz=%f\n",Xxyz,Zxyz); -} - -void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul, double& gmul, double& bmul) const -{ - - clip (temp, green, equal); - - //printf("temp=%d green=%.3f equal=%.3f\n", (int)temp, (float) green, (float) equal); - - //variables for CRI and display Lab, and palette - double xD, yD, x_D, y_D, interm; - double m1, m2; - - double x, y, z; - double Xchk[50], Ychk[50], Zchk[50]; //50 : I think it's a good limit for number of color : for CRI and Palette - double Xcam02[50], Ycam02[50], Zcam02[50]; - - double XchkLamp[50], YchkLamp[50], ZchkLamp[50]; - double Xcam02Lamp[50], Ycam02Lamp[50], Zcam02Lamp[50]; - const double epsilon = 0.008856; //Lab - const double whiteD50[3] = {0.9646019585, 1.0, 0.8244507152}; //calculate with this tool : spect 5nm - double CAM02BB00, CAM02BB01, CAM02BB02, CAM02BB10, CAM02BB11, CAM02BB12, CAM02BB20, CAM02BB21, CAM02BB22; //for CIECAT02 - - double xr[50], yr[50], zr[50]; - double fx[50], fy[50], fz[50]; - -// bool palette = false; - // double tempalet; // correlated temperature - // We first test for specially handled methods - if (method == "Daylight" ) { - spectrum_to_xyz_preset(Daylight5300_spect, x, y, z); - } else if(method == "Cloudy" ) { - spectrum_to_xyz_preset(Cloudy6200_spect, x, y, z); - } else if(method == "Shade" ) { - spectrum_to_xyz_preset(Shade7600_spect, x, y, z); - } else if(method == "Tungsten" ) { - spectrum_to_xyz_preset(A2856_spect, x, y, z); - } else if(method == "Fluo F1" ) { - spectrum_to_xyz_preset(FluoF1_spect, x, y, z); - } else if(method == "Fluo F2" ) { - spectrum_to_xyz_preset(FluoF2_spect, x, y, z); - } else if(method == "Fluo F3" ) { - spectrum_to_xyz_preset(FluoF3_spect, x, y, z); - } else if(method == "Fluo F4" ) { - spectrum_to_xyz_preset(FluoF4_spect, x, y, z); - } else if(method == "Fluo F5" ) { - spectrum_to_xyz_preset(FluoF5_spect, x, y, z); - } else if(method == "Fluo F6" ) { - spectrum_to_xyz_preset(FluoF6_spect, x, y, z); - } else if(method == "Fluo F7" ) { - spectrum_to_xyz_preset(FluoF7_spect, x, y, z); - } else if(method == "Fluo F8" ) { - spectrum_to_xyz_preset(FluoF8_spect, x, y, z); - } else if(method == "Fluo F9" ) { - spectrum_to_xyz_preset(FluoF9_spect, x, y, z); - } else if(method == "Fluo F10" ) { - spectrum_to_xyz_preset(FluoF10_spect, x, y, z); - } else if(method == "Fluo F11" ) { - spectrum_to_xyz_preset(FluoF11_spect, x, y, z); - } else if(method == "Fluo F12" ) { - spectrum_to_xyz_preset(FluoF12_spect, x, y, z); - } else if(method == "HMI Lamp" ) { - spectrum_to_xyz_preset(HMI_spect, x, y, z); - } else if(method == "GTI Lamp" ) { - spectrum_to_xyz_preset(GTI_spect, x, y, z); - } else if(method == "JudgeIII Lamp" ) { - spectrum_to_xyz_preset(JudgeIII_spect, x, y, z); - } else if(method == "Solux Lamp 3500K" ) { - spectrum_to_xyz_preset(Solux3500_spect, x, y, z); - } else if(method == "Solux Lamp 4100K" ) { - spectrum_to_xyz_preset(Solux4100_spect, x, y, z); - } else if(method == "Solux Lamp 4700K" ) { - spectrum_to_xyz_preset(Solux4700_spect, x, y, z); - } else if(method == "NG Solux Lamp 4700K" ) { - spectrum_to_xyz_preset(NG_Solux4700_spect, x, y, z); - } else if(method == "LED LSI Lumelex 2040") { - spectrum_to_xyz_preset(NG_LEDLSI2040_spect, x, y, z); - } else if(method == "LED CRS SP12 WWMR16" ) { - spectrum_to_xyz_preset(NG_CRSSP12WWMR16_spect, x, y, z); - } else if(method == "Flash 5500K" ) { - spectrum_to_xyz_preset(Flash5500_spect, x, y, z); - } else if(method == "Flash 6000K" ) { - spectrum_to_xyz_preset(Flash6000_spect, x, y, z); - } else if(method == "Flash 6500K" ) { - spectrum_to_xyz_preset(Flash6500_spect, x, y, z); + const auto iterator = spectMap.find(method); + + if (iterator != spectMap.end()) { + spectrum_to_xyz_preset(iterator->second, x, y, z); } else { // otherwise we use the Temp+Green generic solution if (temp <= INITIALBLACKBODY) { @@ -1219,48 +1039,42 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul, spectrum_to_xyz_blackbody(temp, x, y, z); } else { // from 4000K up to 25000K: using the D illuminant (daylight) which is standard + double x_D, y_D; if (temp <= 7000) { x_D = -4.6070e9 / (temp * temp * temp) + 2.9678e6 / (temp * temp) + 0.09911e3 / temp + 0.244063; } else if (temp <= 25000) { x_D = -2.0064e9 / (temp * temp * temp) + 1.9018e6 / (temp * temp) + 0.24748e3 / temp + 0.237040; - } else /*if (temp > 25000)*/ { // above 25000 it's unknown..then I have modified to adjust for underwater - x_D = -2.0064e9 / (temp * temp * temp) + 1.9018e6 / (temp * temp) + 0.24748e3 / temp + 0.237040 - ((temp - 25000) / 25000) * 0.025; //Jacques empirical adjustemnt for very high temp (underwater !) + } else /*if (temp > 25000)*/ { + x_D = -2.0064e9 / (temp * temp * temp) + 1.9018e6 / (temp * temp) + 0.24748e3 / temp + 0.237040 - ((temp - 25000) / 25000) * 0.025; //Jacques empirical adjustment for very high temp (underwater !) } - y_D = (-3.0 * x_D * x_D + 2.87 * x_D - 0.275); //modify blue / red action + y_D = -3.0 * x_D * x_D + 2.87 * x_D - 0.275; //modify blue / red action //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) - interm = (0.0241 + 0.2562 * x_D - 0.734 * y_D); - m1 = (-1.3515 - 1.7703 * x_D + 5.9114 * y_D) / interm; - m2 = (0.03 - 31.4424 * x_D + 30.0717 * y_D) / interm; + double interm = 0.0241 + 0.2562 * x_D - 0.734 * y_D; + double m1 = (-1.3515 - 1.7703 * x_D + 5.9114 * y_D) / interm; + double m2 = (0.03 - 31.4424 * x_D + 30.0717 * y_D) / interm; spectrum_to_xyz_daylight(m1, m2, x, y, z); - xD = x; - yD = y; } } - xD = x; - yD = y; + Xxyz = x / y; + Zxyz = (1.0 - x - y) / y; +} + +void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul, double& gmul, double& bmul) const +{ + clip(temp, green, equal); + double Xwb, Zwb; + temp2mulxyz(temp, method, Xwb, Zwb); + float adj = 1.f; if(equal < 0.9999 || equal > 1.0001 ) { adj = (100.f + ( 1000.f - (1000.f * (float)equal) ) / 20.f) / 100.f; } - //printf("adj=%f\n",adj); - double Xwb = xD / yD; - double Ywb = 1.0; - double Zwb = (1.0 - xD - yD) / yD; - - if (settings->verbose) { - // double u=4*xD/(-2*xD+12*yD+3); - // double v=6*yD/(-2*xD+12*yD+3); - // printf("xD=%f yD=%f u=%f v=%f\n",xD,yD,u,v); - if(settings->CRI_color != 0) { - printf("xD=%f yD=%f === Xwb=%f Ywb=%f Zwb=%f\n", xD, yD, Xwb, Ywb, Zwb); - } - } /*if (isRaw) { rmul = sRGB_xyz[0][0]*X + sRGB_xyz[0][1]*Y + sRGB_xyz[0][2]*Z; @@ -1268,36 +1082,41 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul, bmul = sRGB_xyz[2][0]*X + sRGB_xyz[2][1]*Y + sRGB_xyz[2][2]*Z; } else {*/ //recalculate channels multipliers with new values of XYZ tue to whitebalance - rmul = sRGBd65_xyz[0][0] * Xwb * adj + sRGBd65_xyz[0][1] * Ywb + sRGBd65_xyz[0][2] * Zwb / adj; // Jacques' empirical modification 5/2013 - gmul = sRGBd65_xyz[1][0] * Xwb + sRGBd65_xyz[1][1] * Ywb + sRGBd65_xyz[1][2] * Zwb; - bmul = sRGBd65_xyz[2][0] * Xwb * adj + sRGBd65_xyz[2][1] * Ywb + sRGBd65_xyz[2][2] * Zwb / adj; + rmul = sRGBd65_xyz[0][0] * Xwb * adj + sRGBd65_xyz[0][1] + sRGBd65_xyz[0][2] * Zwb / adj; // Jacques' empirical modification 5/2013 + gmul = sRGBd65_xyz[1][0] * Xwb + sRGBd65_xyz[1][1] + sRGBd65_xyz[1][2] * Zwb; + bmul = sRGBd65_xyz[2][0] * Xwb * adj + sRGBd65_xyz[2][1] + sRGBd65_xyz[2][2] * Zwb / adj; //}; gmul /= green; //printf("rmul=%f gmul=%f bmul=%f\n",rmul, gmul, bmul); - double max = rmul; - - if (gmul > max) { - max = gmul; - } - - if (bmul > max) { - max = bmul; - } + double max = rtengine::max(rmul, gmul, bmul); rmul /= max; gmul /= max; bmul /= max; - // begin CRI_RT : color rendering index RT - adaptation of CRI by J.Desmis - // CRI = 100 for Blackbody and Daylight - // calculate from spectral data values X, Y, Z , for color of colorchecker24 , SG, DC, JDC_468 - //only for lamp different of tungstene - //first calcul with illuminant (choice) - // and calcul with : blackbody at equivalent temp of lamp - if(settings->CRI_color != 0) //activate if CRi_color !=0 + if(settings->CRI_color != 0) { //activate if CRi_color !=0 + // begin CRI_RT : color rendering index RT - adaptation of CRI by J.Desmis + // CRI = 100 for Blackbody and Daylight + // calculate from spectral data values X, Y, Z , for color of colorchecker24 , SG, DC, JDC_468 + // only for lamp different of tungstene + // first calcul with illuminant (choice) + // and calcul with : blackbody at equivalent temp of lamp // CRI_color-1 = dispaly Lab values of color CRI_color -1 - { + const double whiteD50[3] = {0.9646019585, 1.0, 0.8244507152}; //calculate with this tool : spect 5nm + double CAM02BB00, CAM02BB01, CAM02BB02, CAM02BB10, CAM02BB11, CAM02BB12, CAM02BB20, CAM02BB21, CAM02BB22; //for CIECAT02 + double Xchk[50], Ychk[50], Zchk[50]; //50 : I think it's a good limit for number of color : for CRI and Palette + double Xcam02[50], Ycam02[50], Zcam02[50]; + + double XchkLamp[50], YchkLamp[50], ZchkLamp[50]; + double Xcam02Lamp[50], Ycam02Lamp[50], Zcam02Lamp[50]; + const double epsilon = 0.008856; //Lab + + double xr[50], yr[50], zr[50]; + double fx[50], fy[50], fz[50]; + double x, y, z; + double Ywb = 1.0; + int illum; int numero_color = settings->CRI_color - 1; diff --git a/rtengine/colortemp.h b/rtengine/colortemp.h index 2d346dd81..d96e6f5ce 100644 --- a/rtengine/colortemp.h +++ b/rtengine/colortemp.h @@ -19,22 +19,19 @@ #ifndef _COLORTEMP_ #define _COLORTEMP_ -#include #include - -#define pow_F(a,b) (xexpf(b*xlogf(a))) +#include namespace rtengine { -#define MINTEMP 1500 -#define MAXTEMP 60000 -#define MINGREEN 0.02 -#define MAXGREEN 10.0 -#define MINEQUAL 0.8 -#define MAXEQUAL 1.5 - -#define INITIALBLACKBODY 4000 +constexpr double MINTEMP = 1500.0; +constexpr double MAXTEMP = 60000.0; +constexpr double MINGREEN = 0.02; +constexpr double MAXGREEN = 10.0; +constexpr double MINEQUAL = 0.8; +constexpr double MAXEQUAL = 1.5; +constexpr double INITIALBLACKBODY = 4000.0; class ColorTemp @@ -49,12 +46,12 @@ private: static void clip (double &temp, double &green, double &equal); int XYZtoCorColorTemp(double x0, double y0 , double z0, double &temp) const; void temp2mul (double temp, double green, double equal, double& rmul, double& gmul, double& bmul) const; - + const static std::map spectMap; public: ColorTemp () : temp(-1.), green(-1.), equal (1.), method("Custom") {} explicit ColorTemp (double e) : temp(-1.), green(-1.), equal (e), method("Custom") {} - ColorTemp (double t, double g, double e, const Glib::ustring &m); + ColorTemp (double t, double g, double e, const std::string &m); ColorTemp (double mulr, double mulg, double mulb, double e); void update (const double rmul, const double gmul, const double bmul, const double equal, const double tempBias=0.0) @@ -95,7 +92,7 @@ public: } void mul2temp (const double rmul, const double gmul, const double bmul, const double equal, double& temp, double& green) const; - static void temp2mulxyz (double tem, double gree, const std::string &method, double &Xxyz, double &Zxyz); + 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 CAT02 (Imagefloat* baseImg, const ProcParams* params); diff --git a/rtengine/curves.cc b/rtengine/curves.cc index 3096f19f4..db6c4c5f5 100644 --- a/rtengine/curves.cc +++ b/rtengine/curves.cc @@ -476,14 +476,10 @@ void CurveFactory::complexsgnCurve (bool & autili, bool & butili, bool & ccutil } -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - SSEFUNCTION void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, double hlcomprthresh, double shcompr, double br, double contr, - procparams::ToneCurveParams::eTCModeId curveMode, const std::vector& curvePoints, - procparams::ToneCurveParams::eTCModeId curveMode2, const std::vector& curvePoints2, + const std::vector& curvePoints, + const std::vector& curvePoints2, LUTu & histogram, LUTf & hlCurve, LUTf & shCurve, LUTf & outCurve, LUTu & outBeforeCCurveHistogram, @@ -1360,7 +1356,7 @@ void ColorGradientCurve::Reset() lut3.reset(); } -void ColorGradientCurve::SetXYZ(const Curve *pCurve, const double xyz_rgb[3][3], const double rgb_xyz[3][3], float satur, float lumin) +void ColorGradientCurve::SetXYZ(const Curve *pCurve, const double xyz_rgb[3][3], float satur, float lumin) { if (pCurve->isIdentity()) { lut1.reset(); @@ -1500,7 +1496,7 @@ void ColorGradientCurve::SetXYZ(const Curve *pCurve, const double xyz_rgb[3][3], */ } -void ColorGradientCurve::SetXYZ(const std::vector &curvePoints, const double xyz_rgb[3][3], const double rgb_xyz[3][3], float satur, float lumin) +void ColorGradientCurve::SetXYZ(const std::vector &curvePoints, const double xyz_rgb[3][3], float satur, float lumin) { std::unique_ptr tcurve; @@ -1509,11 +1505,11 @@ void ColorGradientCurve::SetXYZ(const std::vector &curvePoints, const do } if (tcurve) { - SetXYZ(tcurve.get(), xyz_rgb, rgb_xyz, satur, lumin); + SetXYZ(tcurve.get(), xyz_rgb, satur, lumin); } } -void ColorGradientCurve::SetRGB(const Curve *pCurve, const double xyz_rgb[3][3], const double rgb_xyz[3][3]) +void ColorGradientCurve::SetRGB(const Curve *pCurve) { if (pCurve->isIdentity()) { lut1.reset(); @@ -1599,7 +1595,7 @@ void ColorGradientCurve::SetRGB(const Curve *pCurve, const double xyz_rgb[3][3], */ } -void ColorGradientCurve::SetRGB(const std::vector &curvePoints, const double xyz_rgb[3][3], const double rgb_xyz[3][3]) +void ColorGradientCurve::SetRGB(const std::vector &curvePoints) { std::unique_ptr tcurve; @@ -1608,7 +1604,7 @@ void ColorGradientCurve::SetRGB(const std::vector &curvePoints, const do } if (tcurve) { - SetRGB(tcurve.get(), xyz_rgb, rgb_xyz); + SetRGB(tcurve.get()); } } @@ -1986,7 +1982,7 @@ void PerceptualToneCurve::Apply(float &r, float &g, float &b, PerceptualToneCurv Ciecam02::jch2xyz_ciecam02float( x, y, z, J, C, h, xw, yw, zw, - f, c, nc, 1, pow1, nbb, ncb, fl, cz, d, aw ); + c, nc, 1, pow1, nbb, ncb, fl, cz, d, aw ); if (!isfinite(x) || !isfinite(y) || !isfinite(z)) { // can happen for colors on the rim of being outside gamut, that worked without chroma scaling but not with. Then we return only the curve's result. diff --git a/rtengine/curves.h b/rtengine/curves.h index c20b78772..c616c94da 100644 --- a/rtengine/curves.h +++ b/rtengine/curves.h @@ -281,7 +281,7 @@ public: public: static void complexCurve (double ecomp, double black, double hlcompr, double hlcomprthresh, double shcompr, double br, double contr, - procparams::ToneCurveParams::eTCModeId curveMode, const std::vector& curvePoints, procparams::ToneCurveParams::eTCModeId curveMode2, const std::vector& curvePoints2, + const std::vector& curvePoints, const std::vector& curvePoints2, LUTu & histogram, LUTf & hlCurve, LUTf & shCurve, LUTf & outCurve, LUTu & outBeforeCCurveHistogram, ToneCurve & outToneCurve, ToneCurve & outToneCurve2, int skip = 1); @@ -687,10 +687,10 @@ public: virtual ~ColorGradientCurve() {}; void Reset(); - void SetXYZ(const Curve *pCurve, const double xyz_rgb[3][3], const double rgb_xyz[3][3], float satur, float lumin); - void SetXYZ(const std::vector &curvePoints, const double xyz_rgb[3][3], const double rgb_xyz[3][3], float satur, float lumin); - void SetRGB(const Curve *pCurve, const double xyz_rgb[3][3], const double rgb_xyz[3][3]); - void SetRGB(const std::vector &curvePoints, const double xyz_rgb[3][3], const double rgb_xyz[3][3]); + void SetXYZ(const Curve *pCurve, const double xyz_rgb[3][3], float satur, float lumin); + void SetXYZ(const std::vector &curvePoints, const double xyz_rgb[3][3], float satur, float lumin); + void SetRGB(const Curve *pCurve); + void SetRGB(const std::vector &curvePoints); /** * @brief Get the value of Red, Green and Blue corresponding to the requested index @@ -801,11 +801,6 @@ class StandardToneCurve : public ToneCurve public: void Apply(float& r, float& g, float& b) const; }; -class StandardToneCurvebw : public ToneCurve -{ -public: - void Apply(float& r, float& g, float& b) const; -}; class AdobeToneCurve : public ToneCurve { @@ -816,27 +811,12 @@ public: void Apply(float& r, float& g, float& b) const; }; -class AdobeToneCurvebw : public ToneCurve -{ -private: - void RGBTone(float& r, float& g, float& b) const; // helper for tone curve - -public: - void Apply(float& r, float& g, float& b) const; -}; - class SatAndValueBlendingToneCurve : public ToneCurve { public: void Apply(float& r, float& g, float& b) const; }; -class SatAndValueBlendingToneCurvebw : public ToneCurve -{ -public: - void Apply(float& r, float& g, float& b) const; -}; - class WeightedStdToneCurve : public ToneCurve { private: @@ -884,14 +864,6 @@ public: void Apply(float& r, float& g, float& b, PerceptualToneCurveState & state) const; }; -class WeightedStdToneCurvebw : public ToneCurve -{ -private: - float Triangle(float refX, float refY, float X2) const; -public: - void Apply(float& r, float& g, float& b) const; -}; - // Standard tone curve inline void StandardToneCurve::Apply (float& r, float& g, float& b) const { @@ -902,16 +874,6 @@ inline void StandardToneCurve::Apply (float& r, float& g, float& b) const g = lutToneCurve[g]; b = lutToneCurve[b]; } -// Standard tone curve -inline void StandardToneCurvebw::Apply (float& r, float& g, float& b) const -{ - - assert (lutToneCurve); - - r = lutToneCurve[r]; - g = lutToneCurve[g]; - b = lutToneCurve[b]; -} // Tone curve according to Adobe's reference implementation // values in 0xffff space @@ -943,33 +905,6 @@ inline void AdobeToneCurve::Apply (float& r, float& g, float& b) const } } } -inline void AdobeToneCurvebw::Apply (float& r, float& g, float& b) const -{ - - assert (lutToneCurve); - - if (r >= g) { - if (g > b) { - RGBTone (r, g, b); // Case 1: r >= g > b - } else if (b > r) { - RGBTone (b, r, g); // Case 2: b > r >= g - } else if (b > g) { - RGBTone (r, b, g); // Case 3: r >= b > g - } else { // Case 4: r >= g == b - r = lutToneCurve[r]; - g = lutToneCurve[g]; - b = g; - } - } else { - if (r >= b) { - RGBTone (g, r, b); // Case 5: g > r >= b - } else if (b > g) { - RGBTone (b, g, r); // Case 6: b > g > r - } else { - RGBTone (g, b, r); // Case 7: g >= b > r - } - } -} inline void AdobeToneCurve::RGBTone (float& r, float& g, float& b) const { @@ -979,14 +914,6 @@ inline void AdobeToneCurve::RGBTone (float& r, float& g, float& b) const b = lutToneCurve[bold]; g = b + ((r - b) * (gold - bold) / (rold - bold)); } -inline void AdobeToneCurvebw::RGBTone (float& r, float& g, float& b) const -{ - float rold = r, gold = g, bold = b; - - r = lutToneCurve[rold]; - b = lutToneCurve[bold]; - g = b + ((r - b) * (gold - bold) / (rold - bold)); -} // Modifying the Luminance channel only inline void LuminanceToneCurve::Apply(float &r, float &g, float &b) const @@ -1019,23 +946,6 @@ inline float WeightedStdToneCurve::Triangle(float a, float a1, float b) const return a1; } -inline float WeightedStdToneCurvebw::Triangle(float a, float a1, float b) const -{ - if (a != b) { - float b1; - float a2 = a1 - a; - - if (b < a) { - b1 = b + a2 * b / a ; - } else { - b1 = b + a2 * (65535.f - b) / (65535.f - a); - } - - return b1; - } - - return a1; -} // Tone curve modifying the value channel only, preserving hue and saturation // values in 0xffff space @@ -1061,28 +971,6 @@ inline void WeightedStdToneCurve::Apply (float& r, float& g, float& b) const b = CLIP(b1 * 0.25f + b2 * 0.25f + b3 * 0.50f); } -inline void WeightedStdToneCurvebw::Apply (float& r, float& g, float& b) const -{ - - assert (lutToneCurve); - - float r1 = lutToneCurve[r]; - float g1 = Triangle(r, r1, g); - float b1 = Triangle(r, r1, b); - - float g2 = lutToneCurve[g]; - float r2 = Triangle(g, g2, r); - float b2 = Triangle(g, g2, b); - - float b3 = lutToneCurve[b]; - float r3 = Triangle(b, b3, r); - float g3 = Triangle(b, b3, g); - - r = CLIP( r1 * 0.50f + r2 * 0.25f + r3 * 0.25f); - g = CLIP(g1 * 0.25f + g2 * 0.50f + g3 * 0.25f); - b = CLIP(b1 * 0.25f + b2 * 0.25f + b3 * 0.50f); -} - // Tone curve modifying the value channel only, preserving hue and saturation // values in 0xffff space inline void SatAndValueBlendingToneCurve::Apply (float& r, float& g, float& b) const @@ -1099,54 +987,20 @@ inline void SatAndValueBlendingToneCurve::Apply (float& r, float& g, float& b) c return; } - bool increase = newLum > lum; - Color::rgb2hsv(r, g, b, h, s, v); - if (increase) { + float dV; + if (newLum > lum) { // Linearly targeting Value = 1 and Saturation = 0 float coef = (newLum - lum) / (65535.f - lum); - float dV = (1.f - v) * coef; + dV = (1.f - v) * coef; s *= 1.f - coef; - Color::hsv2rgb(h, s, v + dV, r, g, b); } else { // Linearly targeting Value = 0 - float coef = (lum - newLum) / lum ; - float dV = v * coef; - Color::hsv2rgb(h, s, v - dV, r, g, b); - } -} - -inline void SatAndValueBlendingToneCurvebw::Apply (float& r, float& g, float& b) const -{ - - assert (lutToneCurve); - - float h, s, v; - float lum = (r + g + b) / 3.f; - //float lum = Color::rgbLuminance(r, g, b); - float newLum = lutToneCurve[lum]; - - if (newLum == lum) { - return; - } - - bool increase = newLum > lum; - - Color::rgb2hsv(r, g, b, h, s, v); - - if (increase) { - // Linearly targeting Value = 1 and Saturation = 0 - float coef = (newLum - lum) / (65535.f - lum); - float dV = (1.f - v) * coef; - s *= 1.f - coef; - Color::hsv2rgb(h, s, v + dV, r, g, b); - } else { - // Linearly targeting Value = 0 - float coef = (lum - newLum) / lum ; - float dV = v * coef; - Color::hsv2rgb(h, s, v - dV, r, g, b); + float coef = (newLum - lum) / lum ; + dV = v * coef; } + Color::hsv2rgb(h, s, v + dV, r, g, b); } } diff --git a/rtengine/dcp.cc b/rtengine/dcp.cc index 43aa98480..f9cdd1c73 100644 --- a/rtengine/dcp.cc +++ b/rtengine/dcp.cc @@ -696,7 +696,9 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : return; } - std::unique_ptr tagDir(ExifManager::parseTIFF(file, false)); + ExifManager exifManager(file, nullptr, true); + exifManager.parseTIFF(false); + std::unique_ptr tagDir(exifManager.roots.at(0)); Tag* tag = tagDir->getTag(toUnderlying(TagKey::CALIBRATION_ILLUMINANT_1)); light_source_1 = diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index d6bac40de..7fef1146f 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -1435,253 +1435,278 @@ int CLASS raw (unsigned row, unsigned col) void CLASS phase_one_flat_field (int is_float, int nc) { - ushort head[8]; - unsigned wide, high, y, x, c, rend, cend, row, col; - float *mrow, num, mult[4]; + ushort uhead[8]; - read_shorts (head, 8); - if (head[2] * head[3] * head[4] * head[5] == 0) return; - wide = head[2] / head[4] + (head[2] % head[4] != 0); - high = head[3] / head[5] + (head[3] % head[5] != 0); - mrow = (float *) calloc (nc*wide, sizeof *mrow); - merror (mrow, "phase_one_flat_field()"); - for (y=0; y < high; y++) { - for (x=0; x < wide; x++) - for (c=0; c < nc; c+=2) { - num = is_float ? getreal(11) : get2()/32768.0; - if (y==0) mrow[c*wide+x] = num; - else mrow[(c+1)*wide+x] = (num - mrow[c*wide+x]) / head[5]; - } - if (y==0) continue; - rend = head[1] + y*head[5]; - for (row = rend-head[5]; - row < raw_height && row < rend && - row < head[1]+head[3]-head[5]; row++) { - for (x=1; x < wide; x++) { - for (c=0; c < nc; c+=2) { - mult[c] = mrow[c*wide+x-1]; - mult[c+1] = (mrow[c*wide+x] - mult[c]) / head[4]; - } - cend = head[0] + x*head[4]; - for (col = cend-head[4]; - col < raw_width && - col < cend && col < head[0]+head[2]-head[4]; col++) { - c = nc > 2 ? FC(row-top_margin,col-left_margin) : 0; - if (!(c & 1)) { - c = RAW(row,col) * mult[c]; - RAW(row,col) = LIM(c,0,65535); - } - for (c=0; c < nc; c+=2) - mult[c] += mult[c+1]; - } - } - for (x=0; x < wide; x++) - for (c=0; c < nc; c+=2) - mrow[c*wide+x] += mrow[(c+1)*wide+x]; + read_shorts (uhead, 8); + if (uhead[2] * uhead[3] * uhead[4] * uhead[5] == 0) { + return; } - } - free (mrow); + const unsigned wide = uhead[2] / uhead[4] + (uhead[2] % uhead[4] != 0); + const unsigned high = uhead[3] / uhead[5] + (uhead[3] % uhead[5] != 0); + const unsigned colLimit = std::min(uhead[0] + uhead[2] - uhead[4], (int)raw_width); + + const float head4 = 1.0 / uhead[4]; + const float head5 = 1.0 / uhead[5]; + + float* mrow = (float *) calloc(nc * wide, sizeof *mrow); + merror(mrow, "phase_one_flat_field()"); + for (unsigned x=0; x < wide; x++) { + for (unsigned c=0; c < nc; c+=2) { + float num = is_float ? getreal(11) : get2() / 32768.f; + mrow[c * wide + x] = num; + } + } + for (unsigned y=1; y < high; y++) { + for (unsigned x=0; x < wide; x++) { + for (unsigned c=0; c < nc; c+=2) { + float num = is_float ? getreal(11) : get2() / 32768.f; + mrow[(c + 1) * wide + x] = (num - mrow[c * wide + x]) * head5; + } + } + const unsigned rend = uhead[1] + y * uhead[5]; + for (unsigned row = rend - uhead[5]; row < raw_height && row < rend && row < uhead[1] + uhead[3] - uhead[5]; row++) { + unsigned cend = uhead[0] + uhead[4]; + const unsigned c0 = FC(row - top_margin, cend - uhead[4] - left_margin); + const unsigned c = nc > 2 ? (c0 & 1) ? FC(row - top_margin, cend - uhead[4] - left_margin + 1) : c0 : 0; + for (unsigned x=1; x < wide; x++, cend += uhead[4]) { + float mult0 = mrow[c * wide + x - 1]; + float mult1 = (mrow[c * wide + x] - mult0) * head4; + if (nc > 2) { + mult0 += (c0 & 1) ? mult1 : 0; + for (unsigned col = cend - uhead[4] + (c0 & 1); col < std::min(colLimit, cend); col += 2) { + unsigned val = RAW(row, col) * mult0; + RAW(row, col) = rtengine::min(val, 65535u); + mult0 += mult1; + mult0 += mult1; // <= this could be reduced to one addition inside the loop, but then the result is not exactly the same as with old code, though it should be even more accurate then + } + } else { + for (unsigned col = cend - uhead[4]; col < std::min(colLimit, cend); col++) { + unsigned val = RAW(row, col) * mult0; + RAW(row, col) = rtengine::min(val, 65535u); + mult0 += mult1; + } + } + } + for (unsigned x = 0; x < wide; x++) { + for (unsigned c = 0; c < nc; c += 2) { + mrow[c * wide + x] += mrow[(c + 1) * wide + x]; + } + } + } + } + free(mrow); } void CLASS phase_one_correct() { - unsigned entries, tag, data, save, col, row, type; - int len, i, j, k, cip, val[4], dev[4], sum, max; - int head[9], diff, mindiff=INT_MAX, off_412=0; - static const signed char dir[12][2] = - { {-1,-1}, {-1,1}, {1,-1}, {1,1}, {-2,0}, {0,-2}, {0,2}, {2,0}, - {-2,-2}, {-2,2}, {2,-2}, {2,2} }; - float poly[8], num, cfrac, frac, mult[2], *yval[2]; - ushort *xval[2]; - int qmult_applied = 0, qlin_applied = 0; + unsigned entries, tag, data, save, col, row, type; + int len, i, j, k, cip, val[4], dev[4], sum, max; + int head[9], diff, mindiff=INT_MAX, off_412=0; + static const signed char dir[12][2] = { {-1,-1}, {-1,1}, {1,-1}, {1,1}, {-2,0}, {0,-2}, {0,2}, {2,0}, {-2,-2}, {-2,2}, {2,-2}, {2,2} }; + float poly[8], num, cfrac, frac, mult[2], *yval[2]; + ushort *xval[2]; + int qmult_applied = 0, qlin_applied = 0; - if (half_size || !meta_length) return; - if (verbose) fprintf (stderr,_("Phase One correction...\n")); - fseek (ifp, meta_offset, SEEK_SET); - order = get2(); - fseek (ifp, 6, SEEK_CUR); - fseek (ifp, meta_offset+get4(), SEEK_SET); - entries = get4(); get4(); - while (entries--) { - tag = get4(); - len = get4(); - data = get4(); - save = ftell(ifp); - fseek (ifp, meta_offset+data, SEEK_SET); - if (tag == 0x419) { /* Polynomial curve */ - for (get4(), i=0; i < 8; i++) - poly[i] = getreal(11); - poly[3] += (ph1.tag_210 - poly[7]) * poly[6] + 1; - for (i=0; i < 0x10000; i++) { - num = (poly[5]*i + poly[3])*i + poly[1]; - curve[i] = LIM(num,0,65535); - } goto apply; /* apply to right half */ - } else if (tag == 0x41a) { /* Polynomial curve */ - for (i=0; i < 4; i++) - poly[i] = getreal(11); - for (i=0; i < 0x10000; i++) { - for (num=0, j=4; j--; ) - num = num * i + poly[j]; - curve[i] = LIM(num+i,0,65535); - } apply: /* apply to whole image */ - for (row=0; row < raw_height; row++) - for (col = (tag & 1)*ph1.split_col; col < raw_width; col++) - RAW(row,col) = curve[RAW(row,col)]; - } else if (tag == 0x400) { /* Sensor defects */ - while ((len -= 8) >= 0) { - col = get2(); - row = get2(); - type = get2(); get2(); - if (col >= raw_width) continue; - if (type == 131 || type == 137) /* Bad column */ - for (row=0; row < raw_height; row++) - if (FC(row-top_margin,col-left_margin) == 1) { - for (sum=i=0; i < 4; i++) - sum += val[i] = raw (row+dir[i][0], col+dir[i][1]); - for (max=i=0; i < 4; i++) { - dev[i] = abs((val[i] << 2) - sum); - if (dev[max] < dev[i]) max = i; - } - RAW(row,col) = (sum - val[max])/3.0 + 0.5; - } else { - for (sum=0, i=8; i < 12; i++) - sum += raw (row+dir[i][0], col+dir[i][1]); - RAW(row,col) = 0.5 + sum * 0.0732233 + - (raw(row,col-2) + raw(row,col+2)) * 0.3535534; - } - else if (type == 129) { /* Bad pixel */ - if (row >= raw_height) continue; - j = (FC(row-top_margin,col-left_margin) != 1) * 4; - for (sum=0, i=j; i < j+8; i++) - sum += raw (row+dir[i][0], col+dir[i][1]); - RAW(row,col) = (sum + 4) >> 3; - } - } - } else if (tag == 0x401) { /* All-color flat fields */ - phase_one_flat_field (1, 2); - } else if (tag == 0x416 || tag == 0x410) { - phase_one_flat_field (0, 2); - } else if (tag == 0x40b) { /* Red+blue flat field */ - phase_one_flat_field (0, 4); - } else if (tag == 0x412) { - fseek (ifp, 36, SEEK_CUR); - diff = abs (get2() - ph1.tag_21a); - if (mindiff > diff) { - mindiff = diff; - off_412 = ftell(ifp) - 38; - } - } else if (tag == 0x41f && !qlin_applied) { /* Quadrant linearization */ - ushort lc[2][2][16], ref[16]; - int qr, qc; - for (qr = 0; qr < 2; qr++) - for (qc = 0; qc < 2; qc++) - for (i = 0; i < 16; i++) - lc[qr][qc][i] = get4(); - for (i = 0; i < 16; i++) { - int v = 0; - for (qr = 0; qr < 2; qr++) - for (qc = 0; qc < 2; qc++) - v += lc[qr][qc][i]; - ref[i] = (v + 2) >> 2; - } - for (qr = 0; qr < 2; qr++) { - for (qc = 0; qc < 2; qc++) { - int cx[19], cf[19]; - for (i = 0; i < 16; i++) { - cx[1+i] = lc[qr][qc][i]; - cf[1+i] = ref[i]; - } - cx[0] = cf[0] = 0; - cx[17] = cf[17] = ((unsigned) ref[15] * 65535) / lc[qr][qc][15]; - cx[18] = cf[18] = 65535; - cubic_spline(cx, cf, 19); - for (row = (qr ? ph1.split_row : 0); - row < (qr ? raw_height : ph1.split_row); row++) - for (col = (qc ? ph1.split_col : 0); - col < (qc ? raw_width : ph1.split_col); col++) - RAW(row,col) = curve[RAW(row,col)]; - } - } - qlin_applied = 1; - } else if (tag == 0x41e && !qmult_applied) { /* Quadrant multipliers */ - float qmult[2][2] = { { 1, 1 }, { 1, 1 } }; - get4(); get4(); get4(); get4(); - qmult[0][0] = 1.0 + getreal(11); - get4(); get4(); get4(); get4(); get4(); - qmult[0][1] = 1.0 + getreal(11); - get4(); get4(); get4(); - qmult[1][0] = 1.0 + getreal(11); - get4(); get4(); get4(); - qmult[1][1] = 1.0 + getreal(11); - for (row=0; row < raw_height; row++) - for (col=0; col < raw_width; col++) { - i = qmult[row >= ph1.split_row][col >= ph1.split_col] * RAW(row,col); - RAW(row,col) = LIM(i,0,65535); - } - qmult_applied = 1; - } else if (tag == 0x431 && !qmult_applied) { /* Quadrant combined */ - ushort lc[2][2][7], ref[7]; - int qr, qc; - for (i = 0; i < 7; i++) - ref[i] = get4(); - for (qr = 0; qr < 2; qr++) - for (qc = 0; qc < 2; qc++) - for (i = 0; i < 7; i++) - lc[qr][qc][i] = get4(); - for (qr = 0; qr < 2; qr++) { - for (qc = 0; qc < 2; qc++) { - int cx[9], cf[9]; - for (i = 0; i < 7; i++) { - cx[1+i] = ref[i]; - cf[1+i] = ((unsigned) ref[i] * lc[qr][qc][i]) / 10000; - } - cx[0] = cf[0] = 0; - cx[8] = cf[8] = 65535; - cubic_spline(cx, cf, 9); - for (row = (qr ? ph1.split_row : 0); - row < (qr ? raw_height : ph1.split_row); row++) - for (col = (qc ? ph1.split_col : 0); - col < (qc ? raw_width : ph1.split_col); col++) - RAW(row,col) = curve[RAW(row,col)]; - } - } - qmult_applied = 1; - qlin_applied = 1; + if (half_size || !meta_length) { + return; + } + if (verbose) { + fprintf (stderr,_("Phase One correction...\n")); + } + fseek (ifp, meta_offset, SEEK_SET); + order = get2(); + fseek (ifp, 6, SEEK_CUR); + fseek (ifp, meta_offset+get4(), SEEK_SET); + entries = get4(); get4(); + while (entries--) { + tag = get4(); + len = get4(); + data = get4(); + save = ftell(ifp); + fseek (ifp, meta_offset+data, SEEK_SET); + if (tag == 0x419) { /* Polynomial curve */ + for (get4(), i=0; i < 8; i++) { + poly[i] = getreal(11); + } + poly[3] += (ph1.tag_210 - poly[7]) * poly[6] + 1; + for (i=0; i < 0x10000; i++) { + num = (poly[5]*i + poly[3])*i + poly[1]; + curve[i] = LIM(num,0,65535); + } + goto apply; /* apply to right half */ + } else if (tag == 0x41a) { /* Polynomial curve */ + for (i=0; i < 4; i++) { + poly[i] = getreal(11); + } + for (i=0; i < 0x10000; i++) { + for (num=0, j=4; j--;) { + num = num * i + poly[j]; + } + curve[i] = LIM(num+i,0,65535); + } + apply: /* apply to whole image */ + #pragma omp parallel for schedule(dynamic,16) + for (int row=0; row < raw_height; row++) { + for (int col = (tag & 1)*ph1.split_col; col < raw_width; col++) { + RAW(row,col) = curve[RAW(row,col)]; + } + } + } else if (tag == 0x400) { /* Sensor defects */ + while ((len -= 8) >= 0) { + col = get2(); + row = get2(); + type = get2(); + get2(); + if (col >= raw_width) continue; + if (type == 131 || type == 137) { /* Bad column */ + for (row=0; row < raw_height; row++) { + if (FC(row-top_margin,col-left_margin) == 1) { + for (sum=i=0; i < 4; i++) + sum += val[i] = raw (row+dir[i][0], col+dir[i][1]); + for (max=i=0; i < 4; i++) { + dev[i] = abs((val[i] << 2) - sum); + if (dev[max] < dev[i]) max = i; + } + RAW(row,col) = (sum - val[max])/3.0 + 0.5; + } else { + for (sum=0, i=8; i < 12; i++) + sum += raw (row+dir[i][0], col+dir[i][1]); + RAW(row,col) = 0.5 + sum * 0.0732233 + (raw(row,col-2) + raw(row,col+2)) * 0.3535534; + } + } + } else if (type == 129) { /* Bad pixel */ + if (row >= raw_height) continue; + j = (FC(row-top_margin,col-left_margin) != 1) * 4; + for (sum=0, i=j; i < j+8; i++) + sum += raw (row+dir[i][0], col+dir[i][1]); + RAW(row,col) = (sum + 4) >> 3; + } + } + } else if (tag == 0x401) { /* All-color flat fields */ + phase_one_flat_field (1, 2); + } else if (tag == 0x416 || tag == 0x410) { + phase_one_flat_field (0, 2); + } else if (tag == 0x40b) { /* Red+blue flat field */ + phase_one_flat_field (0, 4); + } else if (tag == 0x412) { + fseek (ifp, 36, SEEK_CUR); + diff = abs (get2() - ph1.tag_21a); + if (mindiff > diff) { + mindiff = diff; + off_412 = ftell(ifp) - 38; + } + } else if (tag == 0x41f && !qlin_applied) { /* Quadrant linearization */ + ushort lc[2][2][16], ref[16]; + int qr, qc; + for (qr = 0; qr < 2; qr++) + for (qc = 0; qc < 2; qc++) + for (i = 0; i < 16; i++) + lc[qr][qc][i] = get4(); + for (i = 0; i < 16; i++) { + int v = 0; + for (qr = 0; qr < 2; qr++) + for (qc = 0; qc < 2; qc++) + v += lc[qr][qc][i]; + ref[i] = (v + 2) >> 2; + } + for (qr = 0; qr < 2; qr++) { + for (qc = 0; qc < 2; qc++) { + int cx[19], cf[19]; + for (i = 0; i < 16; i++) { + cx[1+i] = lc[qr][qc][i]; + cf[1+i] = ref[i]; + } + cx[0] = cf[0] = 0; + cx[17] = cf[17] = ((unsigned) ref[15] * 65535) / lc[qr][qc][15]; + cx[18] = cf[18] = 65535; + cubic_spline(cx, cf, 19); + #pragma omp parallel for schedule(dynamic,16) + for (int row = (qr ? ph1.split_row : 0); row < (qr ? raw_height : ph1.split_row); row++) + for (int col = (qc ? ph1.split_col : 0); col < (qc ? raw_width : ph1.split_col); col++) + RAW(row,col) = curve[RAW(row,col)]; + } + } + qlin_applied = 1; + } else if (tag == 0x41e && !qmult_applied) { /* Quadrant multipliers */ + float qmult[2][2] = { { 1, 1 }, { 1, 1 } }; + get4(); get4(); get4(); get4(); + qmult[0][0] = 1.0 + getreal(11); + get4(); get4(); get4(); get4(); get4(); + qmult[0][1] = 1.0 + getreal(11); + get4(); get4(); get4(); + qmult[1][0] = 1.0 + getreal(11); + get4(); get4(); get4(); + qmult[1][1] = 1.0 + getreal(11); + #pragma omp parallel for schedule(dynamic,16) + for (int row=0; row < raw_height; row++) { + for (int col=0; col < raw_width; col++) { + int i = qmult[row >= ph1.split_row][col >= ph1.split_col] * RAW(row,col); + RAW(row,col) = LIM(i,0,65535); + } + } + qmult_applied = 1; + } else if (tag == 0x431 && !qmult_applied) { /* Quadrant combined */ + ushort lc[2][2][7], ref[7]; + int qr, qc; + for (i = 0; i < 7; i++) + ref[i] = get4(); + for (qr = 0; qr < 2; qr++) + for (qc = 0; qc < 2; qc++) + for (i = 0; i < 7; i++) + lc[qr][qc][i] = get4(); + for (qr = 0; qr < 2; qr++) { + for (qc = 0; qc < 2; qc++) { + int cx[9], cf[9]; + for (i = 0; i < 7; i++) { + cx[1+i] = ref[i]; + cf[1+i] = ((unsigned) ref[i] * lc[qr][qc][i]) / 10000; + } + cx[0] = cf[0] = 0; + cx[8] = cf[8] = 65535; + cubic_spline(cx, cf, 9); + for (row = (qr ? ph1.split_row : 0); row < (qr ? raw_height : ph1.split_row); row++) + for (col = (qc ? ph1.split_col : 0); col < (qc ? raw_width : ph1.split_col); col++) + RAW(row,col) = curve[RAW(row,col)]; + } + } + qmult_applied = 1; + qlin_applied = 1; + } + fseek (ifp, save, SEEK_SET); + } + if (off_412) { + fseek (ifp, off_412, SEEK_SET); + for (i=0; i < 9; i++) + head[i] = get4() & 0x7fff; + yval[0] = (float *) calloc (head[1]*head[3] + head[2]*head[4], 6); + merror (yval[0], "phase_one_correct()"); + yval[1] = (float *) (yval[0] + head[1]*head[3]); + xval[0] = (ushort *) (yval[1] + head[2]*head[4]); + xval[1] = (ushort *) (xval[0] + head[1]*head[3]); + get2(); + for (i=0; i < 2; i++) + for (j=0; j < head[i+1]*head[i+3]; j++) + yval[i][j] = getreal(11); + for (i=0; i < 2; i++) + for (j=0; j < head[i+1]*head[i+3]; j++) + xval[i][j] = get2(); + for (row=0; row < raw_height; row++) + for (col=0; col < raw_width; col++) { + cfrac = (float) col * head[3] / raw_width; + cfrac -= cip = cfrac; + num = RAW(row,col) * 0.5; + for (i=cip; i < cip+2; i++) { + for (k=j=0; j < head[1]; j++) + if (num < xval[0][k = head[1]*i+j]) + break; + frac = (j == 0 || j == head[1]) ? 0 : (xval[0][k] - num) / (xval[0][k] - xval[0][k-1]); + mult[i-cip] = yval[0][k-1] * frac + yval[0][k] * (1-frac); + } + i = ((mult[0] * (1-cfrac) + mult[1] * cfrac) * row + num) * 2; + RAW(row,col) = LIM(i,0,65535); + } + free (yval[0]); } - fseek (ifp, save, SEEK_SET); - } - if (off_412) { - fseek (ifp, off_412, SEEK_SET); - for (i=0; i < 9; i++) head[i] = get4() & 0x7fff; - yval[0] = (float *) calloc (head[1]*head[3] + head[2]*head[4], 6); - merror (yval[0], "phase_one_correct()"); - yval[1] = (float *) (yval[0] + head[1]*head[3]); - xval[0] = (ushort *) (yval[1] + head[2]*head[4]); - xval[1] = (ushort *) (xval[0] + head[1]*head[3]); - get2(); - for (i=0; i < 2; i++) - for (j=0; j < head[i+1]*head[i+3]; j++) - yval[i][j] = getreal(11); - for (i=0; i < 2; i++) - for (j=0; j < head[i+1]*head[i+3]; j++) - xval[i][j] = get2(); - for (row=0; row < raw_height; row++) - for (col=0; col < raw_width; col++) { - cfrac = (float) col * head[3] / raw_width; - cfrac -= cip = cfrac; - num = RAW(row,col) * 0.5; - for (i=cip; i < cip+2; i++) { - for (k=j=0; j < head[1]; j++) - if (num < xval[0][k = head[1]*i+j]) break; - frac = (j == 0 || j == head[1]) ? 0 : - (xval[0][k] - num) / (xval[0][k] - xval[0][k-1]); - mult[i-cip] = yval[0][k-1] * frac + yval[0][k] * (1-frac); - } - i = ((mult[0] * (1-cfrac) + mult[1] * cfrac) * row + num) * 2; - RAW(row,col) = LIM(i,0,65535); - } - free (yval[0]); - } } void CLASS phase_one_load_raw() @@ -1725,9 +1750,35 @@ unsigned CLASS ph1_bithuff_t::operator() (int nbits, ushort *huff) vbits -= nbits; return c; } -#define ph1_bits(n) ph1_bithuff(n,0) + +inline unsigned CLASS ph1_bithuff_t::operator() (int nbits) +{ +/*RT static UINT64 bitbuf=0; */ +/*RT static int vbits=0; */ + + if (vbits < nbits) { + bitbuf = bitbuf << 32 | get4(); + vbits += 32; + } + unsigned c = bitbuf << (64-vbits) >> (64-nbits); + vbits -= nbits; + return c; +} + +inline unsigned CLASS ph1_bithuff_t::operator() () +{ +/*RT static UINT64 bitbuf=0; */ +/*RT static int vbits=0; */ + return bitbuf = vbits = 0; +} + + +#define ph1_init() ph1_bithuff() +#define ph1_bits(n) ph1_bithuff(n) +#define hb_bits(n) ph1_bithuff(n,0) #define ph1_huff(h) ph1_bithuff(*h,h+1) +#ifndef MYFILE_MMAP void CLASS phase_one_load_raw_c() { static const int length[] = { 8,7,6,9,11,10,5,12,14,13 }; @@ -1751,9 +1802,10 @@ void CLASS phase_one_load_raw_c() read_shorts ((ushort *) rblack[0], raw_width*2); for (i=0; i < 256; i++) curve[i] = i*i / 3.969 + 0.5; + ph1_bithuff_t ph1_bithuff(this, ifp, order); for (row=0; row < raw_height; row++) { fseek (ifp, data_offset + offset[row], SEEK_SET); - ph1_bits(-1); + ph1_init(); pred[0] = pred[1] = 0; for (col=0; col < raw_width; col++) { if (col >= (raw_width & -8)) @@ -1781,7 +1833,92 @@ void CLASS phase_one_load_raw_c() free (pixel); maximum = 0xfffc - ph1.black; } +#else +void CLASS phase_one_load_raw_c() +{ + static const int length[] = { 8,7,6,9,11,10,5,12,14,13 }; + int *offset = (int *)calloc(raw_width * 2 + raw_height * 4, 2); + fseek(ifp, strip_offset, SEEK_SET); + for (int row = 0; row < raw_height; row++) { + offset[row] = get4(); + } + + short (*cblack)[2] = (short (*)[2]) (offset + raw_height); + fseek(ifp, ph1.black_col, SEEK_SET); + if (ph1.black_col) { + read_shorts ((ushort *) cblack[0], raw_height * 2); + } + + short (*rblack)[2] = cblack + raw_height; + fseek(ifp, ph1.black_row, SEEK_SET); + if (ph1.black_row) { + read_shorts ((ushort *) rblack[0], raw_width * 2); + } + + for (int i = 0; i < 256; i++) { + curve[i] = i * i / 3.969 + 0.5; + } + +#ifdef _OPENMP +#pragma omp parallel +#endif +{ + int len[2], pred[2]; + IMFILE ifpthr = *ifp; + ifpthr.plistener = nullptr; + +#ifdef _OPENMP +#pragma omp master +#endif +{ + ifpthr.plistener = ifp->plistener; +} + + ph1_bithuff_t ph1_bithuff(this, &ifpthr, order); + +#ifdef _OPENMP + #pragma omp for schedule(dynamic,16) +#endif + + for (int row = 0; row < raw_height; row++) { + const int shift = 2 * (ph1.format != 8); + fseek(&ifpthr, data_offset + offset[row], SEEK_SET); + ph1_init(); + pred[0] = pred[1] = 0; + for (int col = 0; col < raw_width; col++) { + if (col >= (raw_width & -8)) { + len[0] = len[1] = 14; + } else if ((col & 7) == 0) { + for (int i = 0; i < 2; i++) { + int j; + for (j = 0; j < 5 && !ph1_bits(1); j++) + ; + if (j--) { + len[i] = length[j * 2 + ph1_bits(1)]; + } + } + } + + int i = len[col & 1]; + ushort pixel; + if (i == 14) { + pixel = pred[col & 1] = ph1_bits(16); + } else { + pixel = pred[col & 1] += ph1_bits(i) + 1 - (1 << (i - 1)); + } + if (ph1.format == 5 && pixel < 256) { + pixel = curve[pixel]; + } + int rawVal = (pixel << shift) - ph1.black + cblack[row][col >= ph1.split_col] + rblack[col][row >= ph1.split_row]; + RAW(row,col) = std::max(rawVal, 0); + } + } +} + free(offset); + maximum = 0xfffc - ph1.black; +} +#endif void CLASS parse_hasselblad_gain() { /* @@ -2122,7 +2259,8 @@ void CLASS hasselblad_load_raw() if (!ljpeg_start (&jh, 0)) return; order = 0x4949; - ph1_bits(-1); + ph1_bithuff_t ph1_bithuff(this, ifp, order); + hb_bits(-1); back[4] = (int *) calloc (raw_width, 3*sizeof **back); merror (back[4], "hasselblad_load_raw()"); FORC3 back[c] = back[4] + c*raw_width; @@ -2134,7 +2272,7 @@ void CLASS hasselblad_load_raw() for (s=0; s < tiff_samples*2; s+=2) { FORC(2) len[c] = ph1_huff(jh.huff[0]); FORC(2) { - diff[s+c] = ph1_bits(len[c]); + diff[s+c] = hb_bits(len[c]); if ((diff[s+c] & (1 << (len[c]-1))) == 0) diff[s+c] -= (1 << len[c]) - 1; if (diff[s+c] == 65535) diff[s+c] = -32768; @@ -2354,6 +2492,7 @@ unsigned CLASS pana_bits_t::operator() (int nbits) void CLASS panasonic_load_raw() { + pana_bits_t pana_bits(ifp,load_flags); int row, col, i, j, sh=0, pred[2], nonz[2]; pana_bits(0); @@ -2562,6 +2701,12 @@ void CLASS kodak_radc_load_raw() ((short *)buf)[i] = 2048; for (row=0; row < height; row+=4) { FORC3 mul[c] = getbits(6); + FORC3 { + if (!mul[c]) { + mul[c] = 1; + derror(); + } + } FORC3 { val = ((0x1000000/last[c] + 0x7ff) >> 12) * mul[c]; s = val > 65564 ? 10:12; @@ -2924,9 +3069,13 @@ void CLASS kodak_65000_load_raw() pred[0] = pred[1] = 0; len = MIN (256, width-col); ret = kodak_65000_decode (buf, len); - for (i=0; i < len; i++) - if ((RAW(row,col+i) = curve[ret ? buf[i] : - (pred[i & 1] += buf[i])]) >> 12) derror(); + for (i=0; i < len; i++) { + int idx = ret ? buf[i] : (pred[i & 1] += buf[i]); + if(idx >=0 && idx <= 0xffff) { + if ((RAW(row,col+i) = curve[idx]) >> 12) derror(); + } else + derror(); + } } } @@ -3048,34 +3197,60 @@ void CLASS sony_arw_load_raw() void CLASS sony_arw2_load_raw() { - uchar *data, *dp; - ushort pix[16]; - int row, col, val, max, min, imax, imin, sh, bit, i; - data = (uchar *) malloc (raw_width+1); - merror (data, "sony_arw2_load_raw()"); - for (row=0; row < height; row++) { - fread (data, 1, raw_width, ifp); - for (dp=data, col=0; col < raw_width-30; dp+=16) { - max = 0x7ff & (val = sget4(dp)); - min = 0x7ff & val >> 11; - imax = 0x0f & val >> 22; - imin = 0x0f & val >> 26; - for (sh=0; sh < 4 && 0x80 << sh <= max-min; sh++); - for (bit=30, i=0; i < 16; i++) - if (i == imax) pix[i] = max; - else if (i == imin) pix[i] = min; - else { - pix[i] = ((sget2(dp+(bit >> 3)) >> (bit & 7) & 0x7f) << sh) + min; - if (pix[i] > 0x7ff) pix[i] = 0x7ff; - bit += 7; - } - for (i=0; i < 16; i++, col+=2) - RAW(row,col) = curve[pix[i] << 1]; // >> 2; RT: disabled shifting to avoid precision loss - col -= col & 1 ? 1:31; +#if defined( _OPENMP ) && defined( MYFILE_MMAP ) +#pragma omp parallel +#endif +{ + uchar *data = new (std::nothrow) uchar[raw_width + 1]; + merror(data, "sony_arw2_load_raw()"); + IMFILE ifpthr = *ifp; + int pos = ifpthr.pos; + ushort pix[16]; + +#if defined( _OPENMP ) && defined( MYFILE_MMAP ) + // only master thread will update the progress bar + ifpthr.plistener = nullptr; + #pragma omp master + { + ifpthr.plistener = ifp->plistener; } - } - free (data); + #pragma omp for schedule(dynamic,16) nowait +#endif + + for (int row = 0; row < height; row++) { + fseek(&ifpthr, pos + row * raw_width, SEEK_SET); + fread(data, 1, raw_width, &ifpthr); + uchar *dp = data; + for (int col = 0; col < raw_width - 30; dp += 16) { + int val = sget4(dp); + int max = 0x7ff & val; + int min = 0x7ff & val >> 11; + int imax = 0x0f & val >> 22; + int imin = 0x0f & val >> 26; + int bit = 30; + for (int i = 0; i < 16; i++) { + if (i == imax) { + pix[i] = max; + } else if (i == imin) { + pix[i] = min; + } else { + int sh; + for (sh = 0; sh < 4 && 0x80 << sh <= max - min; sh++) + ; + pix[i] = ((sget2(dp + (bit >> 3)) >> (bit & 7) & 0x7f) << sh) + min; + pix[i] = std::min(pix[i], (ushort)0x7ff); + bit += 7; + } + } + for (int i = 0; i < 16; i++, col += 2) { + RAW(row,col) = curve[pix[i] << 1]; // >> 2; RT: disabled shifting to avoid precision loss + } + col -= col & 1 ? 1:31; + } + } + delete [] data; +} maximum = curve[0x7ff << 1]; // RT: fix maximum. maximum = 16300; // RT: conservative white level tested on various ARW2 cameras. This constant was set in 2013-12-17, may need re-evaluation in the future. } @@ -3085,22 +3260,23 @@ void CLASS samsung_load_raw() int row, col, c, i, dir, op[4], len[4]; order = 0x4949; + ph1_bithuff_t ph1_bithuff(this, ifp, order); for (row=0; row < raw_height; row++) { fseek (ifp, strip_offset+row*4, SEEK_SET); fseek (ifp, data_offset+get4(), SEEK_SET); - ph1_bits(-1); + hb_bits(-1); FORC4 len[c] = row < 2 ? 7:4; for (col=0; col < raw_width; col+=16) { - dir = ph1_bits(1); - FORC4 op[c] = ph1_bits(2); + dir = hb_bits(1); + FORC4 op[c] = hb_bits(2); FORC4 switch (op[c]) { - case 3: len[c] = ph1_bits(4); break; + case 3: len[c] = hb_bits(4); break; case 2: len[c]--; break; case 1: len[c]++; } for (c=0; c < 16; c+=2) { i = len[((c & 1) << 1) | (c >> 3)]; - RAW(row,col+c) = ((signed) ph1_bits(i) << (32-i) >> (32-i)) + + RAW(row,col+c) = ((signed) hb_bits(i) << (32-i) >> (32-i)) + (dir ? RAW(row+(~c | -2),col+c) : col ? RAW(row,col+(c | -2)) : 128); if (c == 14) c = -1; } @@ -3142,27 +3318,28 @@ void CLASS samsung3_load_raw() fseek (ifp, 9, SEEK_CUR); opt = fgetc(ifp); init = (get2(),get2()); + ph1_bithuff_t ph1_bithuff(this, ifp, order); for (row=0; row < raw_height; row++) { fseek (ifp, (data_offset-ftell(ifp)) & 15, SEEK_CUR); - ph1_bits(-1); + hb_bits(-1); mag = 0; pmode = 7; FORC(6) ((ushort *)lent)[c] = row < 2 ? 7:4; prow[ row & 1] = &RAW(row-1,1-((row & 1) << 1)); // green prow[~row & 1] = &RAW(row-2,0); // red and blue for (tab=0; tab+15 < raw_width; tab+=16) { if (~opt & 4 && !(tab & 63)) { - i = ph1_bits(2); - mag = i < 3 ? mag-'2'+"204"[i] : ph1_bits(12); + i = hb_bits(2); + mag = i < 3 ? mag-'2'+"204"[i] : hb_bits(12); } if (opt & 2) - pmode = 7 - 4*ph1_bits(1); - else if (!ph1_bits(1)) - pmode = ph1_bits(3); - if (opt & 1 || !ph1_bits(1)) { - FORC4 len[c] = ph1_bits(2); + pmode = 7 - 4*hb_bits(1); + else if (!hb_bits(1)) + pmode = hb_bits(3); + if (opt & 1 || !hb_bits(1)) { + FORC4 len[c] = hb_bits(2); FORC4 { i = ((row & 1) << 1 | (c & 1)) % 3; - len[c] = len[c] < 3 ? lent[i][0]-'1'+"120"[len[c]] : ph1_bits(4); + len[c] = len[c] < 3 ? lent[i][0]-'1'+"120"[len[c]] : hb_bits(4); lent[i][0] = lent[i][1]; lent[i][1] = len[c]; } @@ -3173,7 +3350,7 @@ void CLASS samsung3_load_raw() ? (tab ? RAW(row,tab-2+(col & 1)) : init) : (prow[col & 1][col-'4'+"0224468"[pmode]] + prow[col & 1][col-'4'+"0244668"[pmode]] + 1) >> 1; - diff = ph1_bits (i = len[c >> 2]); + diff = hb_bits (i = len[c >> 2]); if (diff >> (i-1)) diff -= 1 << i; diff = diff * (mag*2+1) + mag; RAW(row,col) = pred + diff; @@ -4103,7 +4280,6 @@ void CLASS crop_masked_pixels() } } } else { - #pragma omp parallel for for (int row=0; row < height; row++) for (int col=0; col < width; col++) @@ -6208,6 +6384,16 @@ guess_cfa_pc: free (buf); } + /* RT -- do not use CameraCalibration matrices for DNGs - see #4129 */ + for (j=0; j < 4; j++) { + ab[j] = 1; + for (i=0; i < 4; i++) { + cc[0][j][i] = i == j; + cc[1][j][i] = i == j; + } + } + /* RT end */ + for (i=0; i < colors; i++) FORCC cc[cm_D65][i][c] *= ab[i]; if (use_cm) { @@ -9024,6 +9210,10 @@ canon_a5: flip = 6; } else if (load_raw != &CLASS packed_load_raw) maximum = (is_raw == 2 && shot_select) ? 0x2f00 : 0x3e00; + if (!strncmp(model,"X-A10",5)) { + raw_width = 4912; + raw_height = 3278; + } top_margin = (raw_height - height) >> 2 << 1; left_margin = (raw_width - width ) >> 2 << 1; if (width == 2848 || width == 3664) filters = 0x16161616; @@ -9503,20 +9693,24 @@ dng_skip: && cmatrix[0][0] > 0.125) { memcpy (rgb_cam, cmatrix, sizeof cmatrix); raw_color = 0; + if (dng_version && !use_camera_wb) { // RT + raw_color = 1; + } } + // RT -- TODO: check if these special cases are still needed! if(!strncmp(make, "Panasonic", 9) && !strncmp(model, "DMC-LX100",9)) adobe_coeff (make, model); if(!strncmp(make, "Samsung", 7) && !strncmp(model, "GX20",4)) adobe_coeff (make, model); if(!strncmp(make, "Samsung", 7) && !strncmp(model, "NX1",3)) adobe_coeff (make, model); - if((!strncmp(make, "Pentax", 6) && (!strncmp(model, "K10D",4) || !strncmp(model, "K-70",4) || !strncmp(model, "K-1",3))) && filters != 0) + if((!strncmp(make, "Pentax", 6) && (!strncmp(model, "K10D",4) || !strncmp(model, "K-70",4) || !strncmp(model, "K-1",3) || !strncmp(model, "KP",2))) && filters != 0) adobe_coeff (make, model); if(!strncmp(make, "Leica", 5) && !strncmp(model, "Q",1)) adobe_coeff (make, model); if(!strncmp(make, "Leica", 5) && !strncmp(model, "SL",2)) adobe_coeff (make, model); - if(!strncmp(make, "XIAOYI", 6) && !strncmp(model, "M1",2)) + if((!strncmp(make, "XIAOYI", 6) || !strncmp(make, "YI", 2)) && !strncmp(model, "M1",2)) adobe_coeff (make, model); if (raw_color) adobe_coeff (make, model); if (load_raw == &CLASS kodak_radc_load_raw) @@ -9754,11 +9948,45 @@ static void copyFloatDataToInt(float * src, ushort * dst, size_t size, float max fprintf(stderr, "DNG Float: NaN data found in input file\n"); } +static int decompress(size_t srcLen, size_t dstLen, unsigned char *in, unsigned char *out) { + // At least in zlib 1.2.11 the uncompress function is not thread save while it is thread save in zlib 1.2.8 + // This simple replacement is thread save. Used example code from https://zlib.net/zlib_how.html + + int ret; + z_stream strm; + /* allocate inflate state */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit(&strm); + if (ret != Z_OK) { + return ret; + } + strm.avail_out = dstLen; + strm.next_out = out; + strm.avail_in = srcLen; + strm.next_in = in; + ret = inflate(&strm, Z_NO_FLUSH); + switch (ret) { + case Z_NEED_DICT: + ret = Z_DATA_ERROR; /* and fall through */ + case Z_DATA_ERROR: + case Z_MEM_ERROR: + (void)inflateEnd(&strm); + return ret; + } + /* clean up and return */ + (void)inflateEnd(&strm); + return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR; +} + void CLASS deflate_dng_load_raw() { float_raw_image = new float[raw_width * raw_height]; #ifdef _OPENMP -#pragma omp parallel for + #pragma omp parallel for #endif for (size_t i = 0; i < raw_width * raw_height; ++i) float_raw_image[i] = 0.0f; @@ -9815,44 +10043,45 @@ void CLASS deflate_dng_load_raw() { } uLongf dstLen = tile_width * tile_length * 4; -#if defined(_OPENMP) && ZLIB_VER_REVISION == 8 +#ifdef _OPENMP #pragma omp parallel #endif { Bytef * cBuffer = new Bytef[maxCompressed]; Bytef * uBuffer = new Bytef[dstLen]; -#if defined(_OPENMP) && ZLIB_VER_REVISION == 8 -#pragma omp for collapse(2) nowait +#ifdef _OPENMP + #pragma omp for collapse(2) schedule(dynamic) nowait #endif for (size_t y = 0; y < raw_height; y += tile_length) { - for (size_t x = 0; x < raw_width; x += tile_width) { - size_t t = (y / tile_length) * tilesWide + (x / tile_width); -#if defined(_OPENMP) && ZLIB_VER_REVISION == 8 -#pragma omp critical + for (size_t x = 0; x < raw_width; x += tile_width) { + size_t t = (y / tile_length) * tilesWide + (x / tile_width); +#ifdef _OPENMP + #pragma omp critical #endif -{ - fseek(ifp, tileOffsets[t], SEEK_SET); - fread(cBuffer, 1, tileBytes[t], ifp); -} - int err = uncompress(uBuffer, &dstLen, cBuffer, tileBytes[t]); - if (err != Z_OK) { - fprintf(stderr, "DNG Deflate: Failed uncompressing tile %d, with error %d\n", (int)t, err); - } else if (ifd->sample_format == 3) { // Floating point data - int bytesps = ifd->bps >> 3; - size_t thisTileLength = y + tile_length > raw_height ? raw_height - y : tile_length; - size_t thisTileWidth = x + tile_width > raw_width ? raw_width - x : tile_width; - for (size_t row = 0; row < thisTileLength; ++row) { - Bytef * src = uBuffer + row*tile_width*bytesps; - Bytef * dst = (Bytef *)&float_raw_image[(y+row)*raw_width + x]; - if (predFactor) - decodeFPDeltaRow(src, dst, thisTileWidth, tile_width, bytesps, predFactor); - expandFloats(dst, thisTileWidth, bytesps); - } - } else { // 32-bit Integer data - // TODO + { + fseek(ifp, tileOffsets[t], SEEK_SET); + fread(cBuffer, 1, tileBytes[t], ifp); + } + int err = decompress(tileBytes[t], dstLen, cBuffer, uBuffer); + if (err != Z_OK) { + fprintf(stderr, "DNG Deflate: Failed uncompressing tile %d, with error %d\n", (int)t, err); + } else if (ifd->sample_format == 3) { // Floating point data + int bytesps = ifd->bps >> 3; + size_t thisTileLength = y + tile_length > raw_height ? raw_height - y : tile_length; + size_t thisTileWidth = x + tile_width > raw_width ? raw_width - x : tile_width; + for (size_t row = 0; row < thisTileLength; ++row) { + Bytef * src = uBuffer + row*tile_width*bytesps; + Bytef * dst = (Bytef *)&float_raw_image[(y+row)*raw_width + x]; + if (predFactor) { + decodeFPDeltaRow(src, dst, thisTileWidth, tile_width, bytesps, predFactor); + } + expandFloats(dst, thisTileWidth, bytesps); + } + } else { // 32-bit Integer data + // TODO + } } - } } delete [] cBuffer; @@ -9901,4 +10130,4 @@ struct tiff_hdr { /*RT*/#undef CLIP #ifdef __GNUC__ #pragma GCC diagnostic pop -#endif \ No newline at end of file +#endif diff --git a/rtengine/dcraw.h b/rtengine/dcraw.h index a109b43c2..cc1f36484 100644 --- a/rtengine/dcraw.h +++ b/rtengine/dcraw.h @@ -59,8 +59,6 @@ public: ,RT_blacklevel_from_constant(0) ,RT_matrix_from_constant(0) ,getbithuff(this,ifp,zero_after_ff) - ,ph1_bithuff(this,ifp,order) - ,pana_bits(ifp,load_flags) { memset(&hbd, 0, sizeof(hbd)); aber[0]=aber[1]=aber[2]=aber[3]=1; @@ -69,7 +67,6 @@ public: greybox[0]=greybox[1]=0; greybox[2]=greybox[3]= UINT_MAX; } - //int main (int argc, const char **argv); protected: int exif_base, ciff_base, ciff_len; IMFILE *ifp; @@ -285,8 +282,8 @@ void fuji_extend_generic(ushort *linebuf[_ltotal], int line_width, int start, in void fuji_extend_red(ushort *linebuf[_ltotal], int line_width); void fuji_extend_green(ushort *linebuf[_ltotal], int line_width); void fuji_extend_blue(ushort *linebuf[_ltotal], int line_width); -void xtrans_decode_block(struct fuji_compressed_block* info, const struct fuji_compressed_params *params, int cur_line); -void fuji_bayer_decode_block(struct fuji_compressed_block* info, const struct fuji_compressed_params *params, int cur_line); +void xtrans_decode_block(struct fuji_compressed_block* info, const struct fuji_compressed_params *params); +void fuji_bayer_decode_block(struct fuji_compressed_block* info, const struct fuji_compressed_params *params); void fuji_decode_strip(const struct fuji_compressed_params* info_common, int cur_block, INT64 raw_offset, unsigned dsize); void fuji_compressed_load_raw(); void fuji_decode_loop(const struct fuji_compressed_params* common_info, int count, INT64* raw_block_offsets, unsigned *block_sizes); @@ -316,19 +313,45 @@ void parse_qt (int end); // ph1_bithuff(int nbits, ushort *huff); class ph1_bithuff_t { public: - ph1_bithuff_t(DCraw *p,IMFILE *&i,short &o):parent(p),order(o),ifp(i),bitbuf(0),vbits(0){} + ph1_bithuff_t(DCraw *p, IMFILE *i, short &o):parent(p),order(o),ifp(i),bitbuf(0),vbits(0){} unsigned operator()(int nbits, ushort *huff); + unsigned operator()(int nbits); + unsigned operator()(); + ushort get2() { + uchar str[2] = { 0xff,0xff }; + fread (str, 1, 2, ifp); + if (order == 0x4949) { /* "II" means little-endian */ + return str[0] | str[1] << 8; + } else { /* "MM" means big-endian */ + return str[0] << 8 | str[1]; + } + } private: - unsigned get4(){ - return parent->get4(); + inline unsigned get4() { + unsigned val = 0xffffff; + uchar* str = (uchar*)&val; + fread (str, 1, 4, ifp); + if (order == 0x4949) { +#if __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__ + return val; +#else + return str[0] | str[1] << 8 | str[2] << 16 | str[3] << 24; +#endif + } else { +#if __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__ + return str[0] << 24 | str[1] << 16 | str[2] << 8 | str[3]; +#else + return val; +#endif + } } + DCraw *parent; short ℴ - IMFILE *&ifp; + IMFILE* const ifp; UINT64 bitbuf; int vbits; }; -ph1_bithuff_t ph1_bithuff; void phase_one_load_raw_c(); void hasselblad_correct(); @@ -341,18 +364,16 @@ void imacon_full_load_raw(); void packed_load_raw(); void nokia_load_raw(); -// pana_bits(int nbits); class pana_bits_t{ public: - pana_bits_t(IMFILE *&i,unsigned &u):ifp(i),load_flags(u),vbits(0){} + pana_bits_t(IMFILE *i, unsigned &u): ifp(i), load_flags(u), vbits(0) {} unsigned operator()(int nbits); private: - IMFILE *&ifp; + IMFILE *ifp; unsigned &load_flags; uchar buf[0x4000]; int vbits; }; -pana_bits_t pana_bits; void canon_rmf_load_raw(); void panasonic_load_raw(); diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 3cf16762d..40e74a662 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -168,7 +168,7 @@ void Crop::update (int todo) bool needstransform = parent->ipf.needsTransform(); - if (todo & (M_INIT | M_LINDENOISE)) { + if (todo & (M_INIT | M_LINDENOISE | M_HDR)) { MyMutex::MyLock lock (parent->minit); // Also used in improccoord int tr = getCoarseBitMask (params.coarse); @@ -228,18 +228,18 @@ void Crop::update (int todo) if (settings->leveldnautsimpl == 1) { if (params.dirpyrDenoise.Cmethod == "MAN" || params.dirpyrDenoise.Cmethod == "PON" ) { PreviewProps pp (trafx, trafy, trafw * skip, trafh * skip, skip); - parent->imgsrc->getImage (parent->currWB, tr, baseCrop, pp, params.toneCurve, params.icm, params.raw ); + parent->imgsrc->getImage (parent->currWB, tr, origCrop, pp, params.toneCurve, params.raw ); } } else { if (params.dirpyrDenoise.C2method == "MANU") { PreviewProps pp (trafx, trafy, trafw * skip, trafh * skip, skip); - parent->imgsrc->getImage (parent->currWB, tr, baseCrop, pp, params.toneCurve, params.icm, params.raw ); + parent->imgsrc->getImage (parent->currWB, tr, origCrop, pp, params.toneCurve, params.raw ); } } if ((settings->leveldnautsimpl == 1 && params.dirpyrDenoise.Cmethod == "PRE") || (settings->leveldnautsimpl == 0 && params.dirpyrDenoise.C2method == "PREV")) { PreviewProps pp (trafx, trafy, trafw * skip, trafh * skip, skip); - parent->imgsrc->getImage (parent->currWB, tr, baseCrop, pp, params.toneCurve, params.icm, params.raw ); + parent->imgsrc->getImage (parent->currWB, tr, origCrop, pp, params.toneCurve, params.raw ); if ((!isDetailWindow) && parent->adnListener && skip == 1 && params.dirpyrDenoise.enabled) { float lowdenoise = 1.f; @@ -321,15 +321,15 @@ void Crop::update (int todo) //setCropSizes (centerTile_X[poscenterX], centerTile_Y[poscenterY], trafw*skip,trafh*skip , skip, true); // we only need image reduced to 1/4 here - int W = baseCrop->getWidth(); - int H = baseCrop->getHeight(); + int W = origCrop->getWidth(); + int H = origCrop->getHeight(); Imagefloat *provicalc = new Imagefloat ((W + 1) / 2, (H + 1) / 2); //for denoise curves for (int ii = 0; ii < H; ii += 2) { for (int jj = 0; jj < W; jj += 2) { - provicalc->r (ii >> 1, jj >> 1) = baseCrop->r (ii, jj); - provicalc->g (ii >> 1, jj >> 1) = baseCrop->g (ii, jj); - provicalc->b (ii >> 1, jj >> 1) = baseCrop->b (ii, jj); + provicalc->r (ii >> 1, jj >> 1) = origCrop->r (ii, jj); + provicalc->g (ii >> 1, jj >> 1) = origCrop->g (ii, jj); + provicalc->b (ii >> 1, jj >> 1) = origCrop->b (ii, jj); } } @@ -350,7 +350,7 @@ void Crop::update (int todo) LUTf gamcurve (65536, 0); float gam, gamthresh, gamslope; parent->ipf.RGB_denoise_infoGamCurve (params.dirpyrDenoise, parent->imgsrc->isRAW(), gamcurve, gam, gamthresh, gamslope); - parent->ipf.RGB_denoise_info (baseCrop, provicalc, parent->imgsrc->isRAW(), gamcurve, gam, gamthresh, gamslope, params.dirpyrDenoise, parent->imgsrc->getDirPyrDenoiseExpComp(), chaut, Nb, redaut, blueaut, maxredaut, maxblueaut, minredaut, minblueaut, chromina, sigma, lumema, sigma_L, redyel, skinc, nsknc, true); + parent->ipf.RGB_denoise_info (origCrop, provicalc, parent->imgsrc->isRAW(), gamcurve, gam, gamthresh, gamslope, params.dirpyrDenoise, parent->imgsrc->getDirPyrDenoiseExpComp(), chaut, Nb, redaut, blueaut, maxredaut, maxblueaut, minredaut, minblueaut, chromina, sigma, lumema, sigma_L, redyel, skinc, nsknc, true); // printf("redy=%f skin=%f pcskin=%f\n",redyel, skinc,nsknc); // printf("DCROP skip=%d cha=%4.0f Nb=%d red=%4.0f bl=%4.0f redM=%4.0f bluM=%4.0f L=%4.0f sigL=%4.0f Ch=%4.0f Si=%4.0f\n",skip, chaut,Nb, redaut,blueaut, maxredaut, maxblueaut, lumema, sigma_L, chromina, sigma); float multip = 1.f; @@ -451,7 +451,7 @@ void Crop::update (int todo) for (int wcr = 0; wcr <= 2; wcr++) { for (int hcr = 0; hcr <= 2; hcr++) { PreviewProps ppP (coordW[wcr], coordH[hcr], crW, crH, 1); - parent->imgsrc->getImage (parent->currWB, tr, origCropPart, ppP, params.toneCurve, params.icm, params.raw ); + parent->imgsrc->getImage (parent->currWB, tr, origCropPart, ppP, params.toneCurve, params.raw ); // we only need image reduced to 1/4 here for (int ii = 0; ii < crH; ii += 2) { @@ -610,10 +610,10 @@ void Crop::update (int todo) //end evaluate noise } - // if(params.dirpyrDenoise.Cmethod=="AUT" || params.dirpyrDenoise.Cmethod=="PON") {//reinit baseCrop after Auto - if ((settings->leveldnautsimpl == 1 && params.dirpyrDenoise.Cmethod == "AUT") || (settings->leveldnautsimpl == 0 && params.dirpyrDenoise.C2method == "AUTO")) { //reinit baseCrop after Auto + // if(params.dirpyrDenoise.Cmethod=="AUT" || params.dirpyrDenoise.Cmethod=="PON") {//reinit origCrop after Auto + if ((settings->leveldnautsimpl == 1 && params.dirpyrDenoise.Cmethod == "AUT") || (settings->leveldnautsimpl == 0 && params.dirpyrDenoise.C2method == "AUTO")) { //reinit origCrop after Auto PreviewProps pp (trafx, trafy, trafw * skip, trafh * skip, skip); - parent->imgsrc->getImage (parent->currWB, tr, baseCrop, pp, params.toneCurve, params.icm, params.raw ); + parent->imgsrc->getImage (parent->currWB, tr, origCrop, pp, params.toneCurve, params.raw ); } DirPyrDenoiseParams denoiseParams = params.dirpyrDenoise; @@ -630,15 +630,15 @@ void Crop::update (int todo) if ((noiseLCurve || noiseCCurve ) && skip == 1 && denoiseParams.enabled) { //only allocate memory if enabled and skip // we only need image reduced to 1/4 here - int W = baseCrop->getWidth(); - int H = baseCrop->getHeight(); + int W = origCrop->getWidth(); + int H = origCrop->getHeight(); calclum = new Imagefloat ((W + 1) / 2, (H + 1) / 2); //for denoise curves for (int ii = 0; ii < H; ii += 2) { for (int jj = 0; jj < W; jj += 2) { - calclum->r (ii >> 1, jj >> 1) = baseCrop->r (ii, jj); - calclum->g (ii >> 1, jj >> 1) = baseCrop->g (ii, jj); - calclum->b (ii >> 1, jj >> 1) = baseCrop->b (ii, jj); + calclum->r (ii >> 1, jj >> 1) = origCrop->r (ii, jj); + calclum->g (ii >> 1, jj >> 1) = origCrop->g (ii, jj); + calclum->b (ii >> 1, jj >> 1) = origCrop->b (ii, jj); } } @@ -653,8 +653,8 @@ void Crop::update (int todo) if (skip == 1 && denoiseParams.enabled) { int kall = 0; - float chaut, redaut, blueaut, maxredaut, maxblueaut, nresi, highresi; - parent->ipf.RGB_denoise (kall, baseCrop, baseCrop, calclum, parent->denoiseInfoStore.ch_M, parent->denoiseInfoStore.max_r, parent->denoiseInfoStore.max_b, parent->imgsrc->isRAW(), /*Roffset,*/ denoiseParams, parent->imgsrc->getDirPyrDenoiseExpComp(), noiseLCurve, noiseCCurve, chaut, redaut, blueaut, maxredaut, maxblueaut, nresi, highresi); + float nresi, highresi; + parent->ipf.RGB_denoise (kall, origCrop, origCrop, calclum, parent->denoiseInfoStore.ch_M, parent->denoiseInfoStore.max_r, parent->denoiseInfoStore.max_b, parent->imgsrc->isRAW(), /*Roffset,*/ denoiseParams, parent->imgsrc->getDirPyrDenoiseExpComp(), noiseLCurve, noiseCCurve, nresi, highresi); if (parent->adnListener) { parent->adnListener->noiseChanged (nresi, highresi); @@ -673,7 +673,7 @@ void Crop::update (int todo) } } - parent->imgsrc->convertColorSpace (baseCrop, params.icm, parent->currWB); + parent->imgsrc->convertColorSpace (origCrop, params.icm, parent->currWB); delete [] min_r; delete [] min_b; @@ -690,6 +690,79 @@ void Crop::update (int todo) // has to be called after setCropSizes! Tools prior to this point can't handle the Edit mechanism, but that shouldn't be a problem. createBuffer (cropw, croph); + std::unique_ptr fattalCrop; + if ((todo & M_HDR) && params.fattal.enabled) { + Imagefloat *f = origCrop; + int fw = skips(parent->fw, skip); + int fh = skips(parent->fh, skip); + bool need_cropping = false; + bool need_fattal = true; + + if (trafx || trafy || trafw != fw || trafh != fh) { + need_cropping = true; + // fattal needs to work on the full image. So here we get the full + // image from imgsrc, and replace the denoised crop in case + if (!params.dirpyrDenoise.enabled && skip == 1 && parent->fattal_11_dcrop_cache) { + f = parent->fattal_11_dcrop_cache; + need_fattal = false; + } else { + f = new Imagefloat(fw, fh); + fattalCrop.reset(f); + PreviewProps pp (0, 0, parent->fw, parent->fh, skip); + int tr = getCoarseBitMask(params.coarse); + parent->imgsrc->getImage(parent->currWB, tr, f, pp, params.toneCurve, params.raw); + parent->imgsrc->convertColorSpace(f, params.icm, parent->currWB); + + if (params.dirpyrDenoise.enabled) { + // copy the denoised crop + int oy = trafy / skip; + int ox = trafx / skip; +#ifdef _OPENMP + #pragma omp parallel for +#endif + for (int y = 0; y < baseCrop->getHeight(); ++y) { + int dy = oy + y; + for (int x = 0; x < baseCrop->getWidth(); ++x) { + int dx = ox + x; + f->r(dy, dx) = baseCrop->r(y, x); + f->g(dy, dx) = baseCrop->g(y, x); + f->b(dy, dx) = baseCrop->b(y, x); + } + } + } else if (skip == 1) { + parent->fattal_11_dcrop_cache = f; // cache this globally + fattalCrop.release(); + } + } + } + if (need_fattal) { + parent->ipf.ToneMapFattal02(f); + } + + // crop back to the size expected by the rest of the pipeline + if (need_cropping) { + Imagefloat *c = origCrop; + + int oy = trafy / skip; + int ox = trafx / skip; +#ifdef _OPENMP + #pragma omp parallel for +#endif + for (int y = 0; y < trafh; ++y) { + int cy = y + oy; + for (int x = 0; x < trafw; ++x) { + int cx = x + ox; + c->r(y, x) = f->r(cy, cx); + c->g(y, x) = f->g(cy, cx); + c->b(y, x) = f->b(cy, cx); + } + } + baseCrop = c; + } else { + baseCrop = f; + } + } + // transform if (needstransform || ((todo & (M_TRANSFORM | M_RGBCURVE)) && params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled && !params.colorappearance.enabled)) { if (!transCrop) { @@ -698,9 +771,7 @@ void Crop::update (int todo) if (needstransform) parent->ipf.transform (baseCrop, transCrop, cropx / skip, cropy / skip, trafx / skip, trafy / skip, skips (parent->fw, skip), skips (parent->fh, skip), parent->getFullWidth(), parent->getFullHeight(), - parent->imgsrc->getMetaData()->getFocalLen(), parent->imgsrc->getMetaData()->getFocalLen35mm(), - parent->imgsrc->getMetaData()->getFocusDist(), - parent->imgsrc->getMetaData()->getFNumber(), + parent->imgsrc->getMetaData(), parent->imgsrc->getRotateDegree(), false); else { baseCrop->copyData (transCrop); @@ -717,6 +788,28 @@ void Crop::update (int todo) transCrop = nullptr; } + if (params.spot.enabled) { + if (todo & M_SPOT) { + if(!spotCrop) { + spotCrop = new Imagefloat (cropw, croph); + } + baseCrop->copyData (spotCrop); + + PreviewProps pp (cropx, cropy, cropw, croph, skip); + parent->ipf.removeSpots (spotCrop, params.spot.entries, pp); + } + } else { + if (spotCrop) { + delete spotCrop; + } + + spotCrop = NULL; + } + + if (spotCrop) { + baseCrop = spotCrop; + } + if ((todo & (M_TRANSFORM | M_RGBCURVE)) && params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled && !params.colorappearance.enabled) { const int W = baseCrop->getWidth(); @@ -762,31 +855,10 @@ void Crop::update (int todo) parent->imgsrc->getGamma()); }*/ - if (params.spot.enabled) { - if (todo & M_SPOT) { - if(!spotCrop) { - spotCrop = new Imagefloat (cropw, croph); - } - baseCrop->copyData (spotCrop); - - PreviewProps pp (cropx, cropy, cropw, croph, skip); - parent->ipf.removeSpots (spotCrop, params.spot.entries, pp); - } - } else { - if (spotCrop) { - delete spotCrop; - spotCrop = NULL; - } - } - - if (spotCrop) { - baseCrop = spotCrop; - } - if (todo & M_RGBCURVE) { double rrm, ggm, bbm; DCPProfile::ApplyState as; - DCPProfile *dcpProf = parent->imgsrc->getDCP (params.icm, parent->currWB, as); + DCPProfile *dcpProf = parent->imgsrc->getDCP (params.icm, as); LUTu histToneCurve; parent->ipf.rgbProc (baseCrop, laboCrop, this, parent->hltonecurve, parent->shtonecurve, parent->tonecurve, cshmap, @@ -824,7 +896,6 @@ void Crop::update (int todo) bool ccutili = parent->ccutili; bool clcutili = parent->clcutili; bool cclutili = parent->cclutili; - bool wavcontlutili = parent->wavcontlutili; LUTu dummy; // parent->ipf.MSR(labnCrop, labnCrop->W, labnCrop->H, 1); @@ -944,7 +1015,7 @@ void Crop::update (int todo) params.wavelet.getCurves (wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL); - parent->ipf.ip_wavelet (labnCrop, labnCrop, kall, WaveParams, wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, parent->wavclCurve, wavcontlutili, skip); + parent->ipf.ip_wavelet (labnCrop, labnCrop, kall, WaveParams, wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, parent->wavclCurve, skip); } // } @@ -967,7 +1038,6 @@ void Crop::update (int todo) // end calculation adaptation scene luminosity } - int begh = 0, endh = labnCrop->H; bool execsharp = false; if (skip == 1) { @@ -980,13 +1050,13 @@ void Crop::update (int todo) if (settings->ciecamfloat) { float d, dj, yb; // not used after this block - parent->ipf.ciecam_02float (cieCrop, float (adap), begh, endh, 1, 2, labnCrop, ¶ms, parent->customColCurve1, parent->customColCurve2, parent->customColCurve3, + parent->ipf.ciecam_02float (cieCrop, float (adap), 1, 2, labnCrop, ¶ms, parent->customColCurve1, parent->customColCurve2, parent->customColCurve3, dummy, dummy, parent->CAMBrightCurveJ, parent->CAMBrightCurveQ, parent->CAMMean, 5, skip, execsharp, d, dj, yb, 1); } else { - double dd, dj, yb; // not used after this block + double dd, dj; // not used after this block - parent->ipf.ciecam_02 (cieCrop, adap, begh, endh, 1, 2, labnCrop, ¶ms, parent->customColCurve1, parent->customColCurve2, parent->customColCurve3, - dummy, dummy, parent->CAMBrightCurveJ, parent->CAMBrightCurveQ, parent->CAMMean, 5, skip, execsharp, dd, dj, yb, 1); + parent->ipf.ciecam_02 (cieCrop, adap, 1, 2, labnCrop, ¶ms, parent->customColCurve1, parent->customColCurve2, parent->customColCurve3, + dummy, dummy, parent->CAMBrightCurveJ, parent->CAMBrightCurveQ, parent->CAMMean, 5, skip, execsharp, dd, dj, 1); } } else { // CIECAM is disbaled, we free up its image buffer to save some space @@ -1106,8 +1176,7 @@ bool check_need_larger_crop_for_lcp_distortion (int fw, int fh, int x, int y, in return false; } - return (params.lensProf.lcpFile.length() > 0 && - params.lensProf.useDist); + return (params.lensProf.useDist && (params.lensProf.useLensfun() || params.lensProf.useLcp())); } } // namespace @@ -1163,6 +1232,7 @@ bool Crop::setCropSizes (int rcx, int rcy, int rcw, int rch, int skip, bool inte ory = by1; orw = bw; orh = bh; + ProcParams& params = parent->params; parent->ipf.transCoord (parent->fw, parent->fh, bx1, by1, bw, bh, orx, ory, orw, orh); @@ -1202,6 +1272,8 @@ bool Crop::setCropSizes (int rcx, int rcy, int rcw, int rch, int skip, bool inte orh = min (y2 - y1, parent->fh - ory); } + leftBorder = skips (rqx1 - bx1, skip); + upperBorder = skips (rqy1 - by1, skip); PreviewProps cp (orx, ory, orw, orh, skip); int orW, orH; @@ -1213,9 +1285,6 @@ bool Crop::setCropSizes (int rcx, int rcy, int rcw, int rch, int skip, bool inte int cw = skips (bw, skip); int ch = skips (bh, skip); - leftBorder = skips (rqx1 - bx1, skip); - upperBorder = skips (rqy1 - by1, skip); - if (settings->verbose) { printf ("setsizes starts (%d, %d, %d, %d, %d, %d)\n", orW, orH, trafw, trafh, cw, ch); } diff --git a/rtengine/demosaic_algos.cc b/rtengine/demosaic_algos.cc index 6a5b8eba8..88d369969 100644 --- a/rtengine/demosaic_algos.cc +++ b/rtengine/demosaic_algos.cc @@ -2612,7 +2612,7 @@ void RawImageSource::igv_interpolate(int winw, int winh) #define FORC(cnt) for (c=0; c < cnt; c++) #define FORC3 FORC(3) -void RawImageSource::ahd_demosaic(int winx, int winy, int winw, int winh) +void RawImageSource::ahd_demosaic() { int i, j, k, top, left, row, col, tr, tc, c, d, val, hm[2]; float (*pix)[4], (*rix)[3]; diff --git a/rtengine/dfmanager.cc b/rtengine/dfmanager.cc index bc35b3c71..a8d31f0ac 100644 --- a/rtengine/dfmanager.cc +++ b/rtengine/dfmanager.cc @@ -334,41 +334,36 @@ void DFManager::init( Glib::ustring pathname ) dfInfo* DFManager::addFileInfo (const Glib::ustring& filename, bool pool) { - auto file = Gio::File::create_for_path (filename); + auto ext = getFileExtension(filename); + + if (ext.empty() || !options.is_extention_enabled(ext)) { + return nullptr; + } + + auto file = Gio::File::create_for_path(filename); if (!file) { return nullptr; } - if (!file->query_exists ()) { + if (!file->query_exists()) { return nullptr; } try { - auto info = file->query_info (); + auto info = file->query_info("standard::name,standard::type,standard::is-hidden"); - if (!info && info->get_file_type () == Gio::FILE_TYPE_DIRECTORY) { + if (!info && info->get_file_type() == Gio::FILE_TYPE_DIRECTORY) { return nullptr; } - if (!options.fbShowHidden && info->is_hidden ()) { + if (!options.fbShowHidden && info->is_hidden()) { return nullptr; } - Glib::ustring ext; - - auto lastdot = info->get_name ().find_last_of ('.'); - if (lastdot != Glib::ustring::npos) { - ext = info->get_name ().substr (lastdot + 1); - } - - if (!options.is_extention_enabled (ext)) { - return nullptr; - } - - RawImage ri (filename); - int res = ri.loadRaw (false); // Read informations about shot + RawImage ri(filename); + int res = ri.loadRaw(false); // Read informations about shot if (res != 0) { return nullptr; @@ -378,32 +373,28 @@ dfInfo* DFManager::addFileInfo (const Glib::ustring& filename, bool pool) if(!pool) { dfInfo n(filename, "", "", 0, 0, 0); - iter = dfList.insert(std::pair< std::string, dfInfo>( "", n ) ); + iter = dfList.emplace("", n); return &(iter->second); } - RawMetaDataLocation rml; - rml.exifBase = ri.get_exifBase(); - rml.ciffBase = ri.get_ciffBase(); - rml.ciffLength = ri.get_ciffLen(); - ImageData idata(filename, &rml); + FramesData idata(filename, std::unique_ptr(new RawMetaDataLocation(ri.get_exifBase(), ri.get_ciffBase(), ri.get_ciffLen())), true); /* Files are added in the map, divided by same maker/model,ISO and shutter*/ - std::string key( dfInfo::key(((Glib::ustring)idata.getMake()).uppercase(), ((Glib::ustring)idata.getModel()).uppercase(), idata.getISOSpeed(), idata.getShutterSpeed()) ); - iter = dfList.find( key ); + std::string key(dfInfo::key(((Glib::ustring)idata.getMake()).uppercase(), ((Glib::ustring)idata.getModel()).uppercase(), idata.getISOSpeed(), idata.getShutterSpeed())); + iter = dfList.find(key); - if( iter == dfList.end() ) { - dfInfo n(filename, ((Glib::ustring)idata.getMake()).uppercase(), ((Glib::ustring)idata.getModel()).uppercase(), idata.getISOSpeed(), idata.getShutterSpeed(), idata.getDateTimeAsTS() ); - iter = dfList.insert(std::pair< std::string, dfInfo>( key, n ) ); + if(iter == dfList.end()) { + dfInfo n(filename, ((Glib::ustring)idata.getMake()).uppercase(), ((Glib::ustring)idata.getModel()).uppercase(), idata.getISOSpeed(), idata.getShutterSpeed(), idata.getDateTimeAsTS()); + iter = dfList.emplace(key, n); } else { - while( iter != dfList.end() && iter->second.key() == key && ABS(iter->second.timestamp - idata.getDateTimeAsTS()) > 60 * 60 * 6 ) { // 6 hour difference + while(iter != dfList.end() && iter->second.key() == key && ABS(iter->second.timestamp - idata.getDateTimeAsTS()) > 60 * 60 * 6) { // 6 hour difference ++iter; } - if( iter != dfList.end() ) { - iter->second.pathNames.push_back( filename ); + if(iter != dfList.end()) { + iter->second.pathNames.push_back(filename); } else { dfInfo n(filename, ((Glib::ustring)idata.getMake()).uppercase(), ((Glib::ustring)idata.getModel()).uppercase(), idata.getISOSpeed(), idata.getShutterSpeed(), idata.getDateTimeAsTS()); - iter = dfList.insert(std::pair< std::string, dfInfo>( key, n ) ); + iter = dfList.emplace(key, n); } } diff --git a/rtengine/dirpyr_equalizer.cc b/rtengine/dirpyr_equalizer.cc index 8f3ebae9f..e20bc04e7 100644 --- a/rtengine/dirpyr_equalizer.cc +++ b/rtengine/dirpyr_equalizer.cc @@ -20,38 +20,27 @@ #include #include -#include "curves.h" -#include "labimage.h" -#include "color.h" -#include "mytime.h" #include "improcfun.h" -#include "rawimagesource.h" #include "array2D.h" #include "rt_math.h" #include "opthelper.h" -#ifdef _OPENMP -#include -#endif -#define CLIPI(a) ((a)>0 ?((a)<32768 ?(a):32768):0) #define RANGEFN(i) ((1000.0f / (i + 1000.0f))) -#define CLIPC(a) ((a)>-32000?((a)<32000?(a):32000):-32000) #define DIRWT(i1,j1,i,j) ( domker[(i1-i)/scale+halfwin][(j1-j)/scale+halfwin] * RANGEFN(fabsf((data_fine[i1][j1]-data_fine[i][j]))) ) namespace rtengine { -static const int maxlevel = 6; -static const float noise = 2000; +constexpr int maxlevel = 6; +constexpr float noise = 2000; //sequence of scales -static const int scales[6] = {1, 2, 4, 8, 16, 32}; +constexpr int scales[maxlevel] = {1, 2, 4, 8, 16, 32}; extern const Settings* settings; //sequence of scales - -SSEFUNCTION void ImProcFunctions :: dirpyr_equalizer(float ** src, float ** dst, int srcwidth, int srcheight, float ** l_a, float ** l_b, float ** dest_a, float ** dest_b, const double * mult, const double dirpyrThreshold, const double skinprot, const bool gamutlab, float b_l, float t_l, float t_r, float b_r, int choice, int scaleprev) +SSEFUNCTION void ImProcFunctions :: dirpyr_equalizer(float ** src, float ** dst, int srcwidth, int srcheight, float ** l_a, float ** l_b, const double * mult, const double dirpyrThreshold, const double skinprot, float b_l, float t_l, float t_r, int scaleprev) { int lastlevel = maxlevel; @@ -94,10 +83,10 @@ SSEFUNCTION void ImProcFunctions :: dirpyr_equalizer(float ** src, float ** dst, } int level; - float multi[6] = {1.f, 1.f, 1.f, 1.f, 1.f, 1.f}; - float scalefl[6]; + float multi[maxlevel] = {1.f, 1.f, 1.f, 1.f, 1.f, 1.f}; + float scalefl[maxlevel]; - for(int lv = 0; lv < 6; lv++) { + for(int lv = 0; lv < maxlevel; lv++) { scalefl[lv] = ((float) scales[lv]) / (float) scaleprev; if(lv >= 1) { @@ -226,12 +215,12 @@ SSEFUNCTION void ImProcFunctions :: dirpyr_equalizer(float ** src, float ** dst, float ** buffer = dirpyrlo[lastlevel - 1]; for(int level = lastlevel - 1; level > 0; level--) { - idirpyr_eq_channel(dirpyrlo[level], dirpyrlo[level - 1], buffer, srcwidth, srcheight, level, multi, dirpyrThreshold, tmpHue, tmpChr, skinprot, gamutlab, b_l, t_l, t_r, b_r, choice ); + idirpyr_eq_channel(dirpyrlo[level], dirpyrlo[level - 1], buffer, srcwidth, srcheight, level, multi, dirpyrThreshold, tmpHue, tmpChr, skinprot, b_l, t_l, t_r); } scale = scales[0]; - idirpyr_eq_channel(dirpyrlo[0], dst, buffer, srcwidth, srcheight, 0, multi, dirpyrThreshold, tmpHue, tmpChr, skinprot, gamutlab, b_l, t_l, t_r, b_r, choice ); + idirpyr_eq_channel(dirpyrlo[0], dst, buffer, srcwidth, srcheight, 0, multi, dirpyrThreshold, tmpHue, tmpChr, skinprot, b_l, t_l, t_r); if(skinprot != 0.f) { for (int i = 0; i < srcheight; i++) { @@ -247,7 +236,6 @@ SSEFUNCTION void ImProcFunctions :: dirpyr_equalizer(float ** src, float ** dst, delete [] tmpHue; } - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #pragma omp parallel for for (int i = 0; i < srcheight; i++) @@ -259,7 +247,7 @@ SSEFUNCTION void ImProcFunctions :: dirpyr_equalizer(float ** src, float ** dst, -void ImProcFunctions :: dirpyr_equalizercam (CieImage *ncie, float ** src, float ** dst, int srcwidth, int srcheight, float ** h_p, float ** C_p, const double * mult, const double dirpyrThreshold, const double skinprot, bool execdir, const bool gamutlab, float b_l, float t_l, float t_r, float b_r, int choice, int scaleprev) +void ImProcFunctions :: dirpyr_equalizercam (CieImage *ncie, float ** src, float ** dst, int srcwidth, int srcheight, float ** h_p, float ** C_p, const double * mult, const double dirpyrThreshold, const double skinprot, bool execdir, float b_l, float t_l, float t_r, int scaleprev) { int lastlevel = maxlevel; @@ -303,10 +291,10 @@ void ImProcFunctions :: dirpyr_equalizercam (CieImage *ncie, float ** src, float int level; - float multi[6] = {1.f, 1.f, 1.f, 1.f, 1.f, 1.f}; - float scalefl[6]; + float multi[maxlevel] = {1.f, 1.f, 1.f, 1.f, 1.f, 1.f}; + float scalefl[maxlevel]; - for(int lv = 0; lv < 6; lv++) { + for(int lv = 0; lv < maxlevel; lv++) { scalefl[lv] = ((float) scales[lv]) / (float) scaleprev; // if(scalefl[lv] < 1.f) multi[lv] = 1.f; else multi[lv]=(float) mult[lv]; @@ -371,7 +359,6 @@ void ImProcFunctions :: dirpyr_equalizercam (CieImage *ncie, float ** src, float idirpyr_eq_channelcam(dirpyrlo[0], dst, buffer, srcwidth, srcheight, 0, multi, dirpyrThreshold, h_p, C_p, skinprot, b_l, t_l, t_r); - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% if(execdir) { #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) @@ -385,20 +372,17 @@ void ImProcFunctions :: dirpyr_equalizercam (CieImage *ncie, float ** src, float dst[i][j] = src[i][j]; } } - } else + } else { for (int i = 0; i < srcheight; i++) for (int j = 0; j < srcwidth; j++) { dst[i][j] = CLIP( buffer[i][j] ); // TODO: Really a clip necessary? } - - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + } } - SSEFUNCTION void ImProcFunctions::dirpyr_channel(float ** data_fine, float ** data_coarse, int width, int height, int level, int scale) { - //scale is spacing of directional averaging weights - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // scale is spacing of directional averaging weights // calculate weights, compute directionally weighted average if(level > 1) { @@ -620,9 +604,7 @@ SSEFUNCTION void ImProcFunctions::dirpyr_channel(float ** data_fine, float ** da } } -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -void ImProcFunctions::idirpyr_eq_channel(float ** data_coarse, float ** data_fine, float ** buffer, int width, int height, int level, float mult[6], const double dirpyrThreshold, float ** hue, float ** chrom, const double skinprot, const bool gamutlab, float b_l, float t_l, float t_r, float b_r , int choice) +void ImProcFunctions::idirpyr_eq_channel(float ** data_coarse, float ** data_fine, float ** buffer, int width, int height, int level, float mult[maxlevel], const double dirpyrThreshold, float ** hue, float ** chrom, const double skinprot, float b_l, float t_l, float t_r) { const float skinprotneg = -skinprot; const float factorHard = (1.f - skinprotneg / 100.f); @@ -635,7 +617,7 @@ void ImProcFunctions::idirpyr_eq_channel(float ** data_coarse, float ** data_fin offs = -1.f; } - float multbis[6]; + float multbis[maxlevel]; multbis[level] = mult[level]; //multbis to reduce artifacts for high values mult @@ -714,7 +696,7 @@ void ImProcFunctions::idirpyr_eq_channel(float ** data_coarse, float ** data_fin } -void ImProcFunctions::idirpyr_eq_channelcam(float ** data_coarse, float ** data_fine, float ** buffer, int width, int height, int level, float mult[6], const double dirpyrThreshold, float ** l_a_h, float ** l_b_c, const double skinprot, float b_l, float t_l, float t_r) +void ImProcFunctions::idirpyr_eq_channelcam(float ** data_coarse, float ** data_fine, float ** buffer, int width, int height, int level, float mult[maxlevel], const double dirpyrThreshold, float ** l_a_h, float ** l_b_c, const double skinprot, float b_l, float t_l, float t_r) { const float skinprotneg = -skinprot; @@ -728,7 +710,7 @@ void ImProcFunctions::idirpyr_eq_channelcam(float ** data_coarse, float ** data_ offs = -1.f; } - float multbis[6]; + float multbis[maxlevel]; multbis[level] = mult[level]; //multbis to reduce artifacts for high values mult diff --git a/rtengine/dynamicprofile.cc b/rtengine/dynamicprofile.cc index 5ac408da5..1afc04446 100644 --- a/rtengine/dynamicprofile.cc +++ b/rtengine/dynamicprofile.cc @@ -72,7 +72,7 @@ bool DynamicProfileRule::operator< (const DynamicProfileRule &other) const } -bool DynamicProfileRule::matches (const rtengine::ImageMetaData *im) const +bool DynamicProfileRule::matches (const rtengine::FramesMetaData *im) const { return (iso (im->getISOSpeed()) && fnumber (im->getFNumber()) diff --git a/rtengine/dynamicprofile.h b/rtengine/dynamicprofile.h index cfe46d9ba..4e6bbbba9 100644 --- a/rtengine/dynamicprofile.h +++ b/rtengine/dynamicprofile.h @@ -48,7 +48,7 @@ public: }; DynamicProfileRule(); - bool matches (const rtengine::ImageMetaData *im) const; + bool matches (const rtengine::FramesMetaData *im) const; bool operator< (const DynamicProfileRule &other) const; int serial_number; diff --git a/rtengine/expo_before_b.cc b/rtengine/expo_before_b.cc index 98fed04f7..f94b2c292 100644 --- a/rtengine/expo_before_b.cc +++ b/rtengine/expo_before_b.cc @@ -80,7 +80,7 @@ void RawImageSource::processRawWhitepoint(float expos, float preser, array2DgetSensorType() == ST_BAYER || ri->getSensorType() == ST_FUJI_XTRANS) { // Demosaic to allow calculation of luminosity. if(ri->getSensorType() == ST_BAYER) { - fast_demosaic (0, 0, W, H); + fast_demosaic(); } else { fast_xtrans_interpolate(); } diff --git a/rtengine/fast_demo.cc b/rtengine/fast_demo.cc index 12286d9f1..6143d172e 100644 --- a/rtengine/fast_demo.cc +++ b/rtengine/fast_demo.cc @@ -52,7 +52,7 @@ LUTf RawImageSource::initInvGrad() #endif //LUTf RawImageSource::invGrad = RawImageSource::initInvGrad(); -SSEFUNCTION void RawImageSource::fast_demosaic(int winx, int winy, int winw, int winh) +SSEFUNCTION void RawImageSource::fast_demosaic() { double progress = 0.0; diff --git a/rtengine/ffmanager.cc b/rtengine/ffmanager.cc index 87ae98905..028b8a79a 100644 --- a/rtengine/ffmanager.cc +++ b/rtengine/ffmanager.cc @@ -21,6 +21,7 @@ #include "rawimage.h" #include "imagedata.h" #include "median.h" +#include "utils.h" namespace rtengine { @@ -288,43 +289,36 @@ void FFManager::init( Glib::ustring pathname ) ffInfo* FFManager::addFileInfo (const Glib::ustring& filename, bool pool) { - auto file = Gio::File::create_for_path (filename); + auto ext = getFileExtension(filename); + + if (ext.empty() || !options.is_extention_enabled(ext)) { + return nullptr; + } + + auto file = Gio::File::create_for_path(filename); if (!file ) { return nullptr; } - if (!file->query_exists ()) { + if (!file->query_exists()) { return nullptr; } try { - auto info = file->query_info (); + auto info = file->query_info("standard::name,standard::type,standard::is-hidden"); - if (!info || info->get_file_type () == Gio::FILE_TYPE_DIRECTORY) { + if (!info || info->get_file_type() == Gio::FILE_TYPE_DIRECTORY) { return nullptr; } - if (!options.fbShowHidden && info->is_hidden ()) { + if (!options.fbShowHidden && info->is_hidden()) { return nullptr; } - Glib::ustring ext; - - auto lastdot = info->get_name ().find_last_of ('.'); - - if (lastdot != Glib::ustring::npos) { - ext = info->get_name ().substr (lastdot + 1); - } - - if (!options.is_extention_enabled (ext)) { - return nullptr; - } - - - RawImage ri (filename); - int res = ri.loadRaw (false); // Read informations about shot + RawImage ri(filename); + int res = ri.loadRaw(false); // Read informations about shot if (res != 0) { return nullptr; @@ -334,32 +328,28 @@ ffInfo* FFManager::addFileInfo (const Glib::ustring& filename, bool pool) if(!pool) { ffInfo n(filename, "", "", "", 0, 0, 0); - iter = ffList.insert(std::pair< std::string, ffInfo>( "", n ) ); + iter = ffList.emplace("", n); return &(iter->second); } - RawMetaDataLocation rml; - rml.exifBase = ri.get_exifBase(); - rml.ciffBase = ri.get_ciffBase(); - rml.ciffLength = ri.get_ciffLen(); - ImageData idata(filename, &rml); + FramesData idata(filename, std::unique_ptr(new RawMetaDataLocation(ri.get_exifBase(), ri.get_ciffBase(), ri.get_ciffLen())), true); /* Files are added in the map, divided by same maker/model,lens and aperture*/ - std::string key( ffInfo::key(idata.getMake(), idata.getModel(), idata.getLens(), idata.getFocalLen(), idata.getFNumber()) ); - iter = ffList.find( key ); + std::string key(ffInfo::key(idata.getMake(), idata.getModel(), idata.getLens(), idata.getFocalLen(), idata.getFNumber())); + iter = ffList.find(key); - if( iter == ffList.end() ) { + if(iter == ffList.end()) { ffInfo n(filename, idata.getMake(), idata.getModel(), idata.getLens(), idata.getFocalLen(), idata.getFNumber(), idata.getDateTimeAsTS()); - iter = ffList.insert(std::pair< std::string, ffInfo>( key, n ) ); + iter = ffList.emplace(key, n); } else { - while( iter != ffList.end() && iter->second.key() == key && ABS(iter->second.timestamp - ri.get_timestamp()) > 60 * 60 * 6 ) { // 6 hour difference + while(iter != ffList.end() && iter->second.key() == key && ABS(iter->second.timestamp - ri.get_timestamp()) > 60 * 60 * 6) { // 6 hour difference ++iter; } - if( iter != ffList.end() ) { - iter->second.pathNames.push_back( filename ); + if(iter != ffList.end()) { + iter->second.pathNames.push_back(filename); } else { ffInfo n(filename, idata.getMake(), idata.getModel(), idata.getLens(), idata.getFocalLen(), idata.getFNumber(), idata.getDateTimeAsTS()); - iter = ffList.insert(std::pair< std::string, ffInfo>( key, n ) ); + iter = ffList.emplace(key, n); } } diff --git a/rtengine/fujicompressed.cc b/rtengine/fujicompressed.cc index 156c338d5..e00e037fc 100644 --- a/rtengine/fujicompressed.cc +++ b/rtengine/fujicompressed.cc @@ -534,7 +534,7 @@ void CLASS fuji_extend_blue (ushort *linebuf[_ltotal], int line_width) fuji_extend_generic (linebuf, line_width, _B2, _B4); } -void CLASS xtrans_decode_block (struct fuji_compressed_block* info, const struct fuji_compressed_params *params, int cur_line) +void CLASS xtrans_decode_block (struct fuji_compressed_block* info, const struct fuji_compressed_params *params) { int r_even_pos = 0, r_odd_pos = 1; int g_even_pos = 0, g_odd_pos = 1; @@ -699,8 +699,7 @@ void CLASS xtrans_decode_block (struct fuji_compressed_block* info, const struct } } -void CLASS fuji_bayer_decode_block (struct fuji_compressed_block *info, const struct fuji_compressed_params *params, - int cur_line) +void CLASS fuji_bayer_decode_block (struct fuji_compressed_block *info, const struct fuji_compressed_params *params) { int r_even_pos = 0, r_odd_pos = 1; int g_even_pos = 0, g_odd_pos = 1; @@ -867,9 +866,9 @@ void CLASS fuji_decode_strip (const struct fuji_compressed_params* info_common, for (cur_line = 0; cur_line < fuji_total_lines; cur_line++) { if (fuji_raw_type == 16) { - xtrans_decode_block (&info, info_common, cur_line); + xtrans_decode_block (&info, info_common); } else { - fuji_bayer_decode_block (&info, info_common, cur_line); + fuji_bayer_decode_block (&info, info_common); } // copy data from line buffers and advance diff --git a/rtengine/green_equil_RT.cc b/rtengine/green_equil_RT.cc index 8b1136359..90c412871 100644 --- a/rtengine/green_equil_RT.cc +++ b/rtengine/green_equil_RT.cc @@ -3,9 +3,10 @@ // Green Equilibration via directional average // // copyright (c) 2008-2010 Emil Martinec +// optimized for speed 2017 Ingo Weyrich // // -// code dated: February 12, 2011 +// code dated: August 25, 2017 // // green_equil_RT.cc is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -21,18 +22,72 @@ // along with this program. If not, see . // //////////////////////////////////////////////////////////////// -#define TS 256 // Tile size #include #include #include - #include "rt_math.h" #include "rawimagesource.h" +#include "opthelper.h" + namespace rtengine { +void RawImageSource::green_equilibrate_global(array2D &rawData) +{ + // global correction + int ng1 = 0, ng2 = 0; + double avgg1 = 0., avgg2 = 0.; + +#ifdef _OPENMP + #pragma omp parallel for reduction(+: ng1, ng2, avgg1, avgg2) schedule(dynamic,16) +#endif + + 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]; + } + + int ng = (W - 2 * border + (FC(i, border) & 1)) / 2; + + if (i & 1) { + avgg2 += avgg; + ng2 += ng; + } else { + avgg1 += avgg; + ng1 += ng; + } + } + + // Avoid division by zero + if(ng1 == 0 || avgg1 == 0.0) { + ng1 = 1; + avgg1 = 1.0; + } + if(ng2 == 0 || avgg2 == 0.0) { + ng2 = 1; + avgg2 = 1.0; + } + + double corrg1 = (avgg1 / ng1 + avgg2 / ng2) / 2.0 / (avgg1 / ng1); + double 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; + + for (int j = border + ((FC(i, border) & 1) ^ 1); j < W - border; j += 2) { + rawData[i][j] *= corrg; + } + } +} + //void green_equilibrate()//for dcraw implementation void RawImageSource::green_equilibrate(float thresh, array2D &rawData) { @@ -42,15 +97,29 @@ void RawImageSource::green_equilibrate(float thresh, array2D &rawData) int height = H, width = W; // local variables - float** rawptr = rawData; - array2D cfa (width, height, rawptr); - //array2D checker (width,height,ARRAY2D_CLEAR_DATA); + array2D cfa(width / 2 + (width & 1), height); +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif - //int verbose=1; + for (int i = 0; i < height; ++i) { + int j = (FC(i, 0) & 1) ^ 1; +#ifdef __SSE2__ - static const float eps = 1.0; //tolerance to avoid dividing by zero + for (; j < width - 7; j += 8) { + STVFU(cfa[i][j >> 1], LC2VFU(rawData[i][j])); + } +#endif + + for (; j < width; j += 2) { + cfa[i][j >> 1] = rawData[i][j]; + } + } + + constexpr float eps = 1.f; //tolerance to avoid dividing by zero + const float thresh6 = 6 * thresh; // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // Fill G interpolated values with border interpolation and input values @@ -59,94 +128,118 @@ void RawImageSource::green_equilibrate(float thresh, array2D &rawData) //int counter, vtest; //The green equilibration algorithm starts here - /* - #ifdef _OPENMP - #pragma omp parallel for - #endif - for (int rr=1; rr < height-1; rr++) - for (int cc=3-(FC(rr,2)&1); cc < width-2; cc+=2) { - - float pcorr = (cfa[rr+1][cc+1]-cfa[rr][cc])*(cfa[rr-1][cc-1]-cfa[rr][cc]); - float mcorr = (cfa[rr-1][cc+1]-cfa[rr][cc])*(cfa[rr+1][cc-1]-cfa[rr][cc]); - - if (pcorr>0 && mcorr>0) {checker[rr][cc]=1;} else {checker[rr][cc]=0;} - - checker[rr][cc]=1;//test what happens if we always interpolate - } - - counter=vtest=0; - */ //now smooth the cfa data #ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) + #pragma omp parallel +#endif + { +#ifdef __SSE2__ + vfloat zd5v = F2V(0.5f); + vfloat onev = F2V(1.f); + vfloat threshv = F2V(thresh); + vfloat thresh6v = F2V(thresh6); + vfloat epsv = F2V(eps); +#endif +#ifdef _OPENMP + #pragma omp for schedule(dynamic,16) #endif - for (int rr = 4; rr < height - 4; rr++) - for (int cc = 5 - (FC(rr, 2) & 1); cc < width - 6; cc += 2) { - //if (checker[rr][cc]) { - //%%%%%%%%%%%%%%%%%%%%%% - //neighbor checking code from Manuel Llorens Garcia - float o1_1 = cfa[(rr - 1)][cc - 1]; - float o1_2 = cfa[(rr - 1)][cc + 1]; - float o1_3 = cfa[(rr + 1)][cc - 1]; - float o1_4 = cfa[(rr + 1)][cc + 1]; - float o2_1 = cfa[(rr - 2)][cc]; - float o2_2 = cfa[(rr + 2)][cc]; - float o2_3 = cfa[(rr)][cc - 2]; - float o2_4 = cfa[(rr)][cc + 2]; + for (int rr = 4; rr < height - 4; rr++) { + int cc = 5 - (FC(rr, 2) & 1); +#ifdef __SSE2__ - float d1 = (o1_1 + o1_2 + o1_3 + o1_4) * 0.25f; - float d2 = (o2_1 + o2_2 + o2_3 + o2_4) * 0.25f; + for (; cc < width - 12; cc += 8) { + //neighbour checking code from Manuel Llorens Garcia + vfloat o1_1 = LVFU(cfa[rr - 1][(cc - 1) >> 1]); + vfloat o1_2 = LVFU(cfa[rr - 1][(cc + 1) >> 1]); + vfloat o1_3 = LVFU(cfa[rr + 1][(cc - 1) >> 1]); + vfloat o1_4 = LVFU(cfa[rr + 1][(cc + 1) >> 1]); + vfloat o2_1 = LVFU(cfa[rr - 2][cc >> 1]); + vfloat o2_2 = LVFU(cfa[rr + 2][cc >> 1]); + vfloat o2_3 = LVFU(cfa[rr][(cc >> 1) - 1]); + vfloat o2_4 = LVFU(cfa[rr][(cc >> 1) + 1]); - float c1 = (fabs(o1_1 - o1_2) + fabs(o1_1 - o1_3) + fabs(o1_1 - o1_4) + fabs(o1_2 - o1_3) + fabs(o1_3 - o1_4) + fabs(o1_2 - o1_4)) / 6.f; - float c2 = (fabs(o2_1 - o2_2) + fabs(o2_1 - o2_3) + fabs(o2_1 - o2_4) + fabs(o2_2 - o2_3) + fabs(o2_3 - o2_4) + fabs(o2_2 - o2_4)) / 6.f; - //%%%%%%%%%%%%%%%%%%%%%% + vfloat d1 = (o1_1 + o1_2 + o1_3 + o1_4); + vfloat d2 = (o2_1 + o2_2 + o2_3 + o2_4); - //vote1=(checker[rr-2][cc]+checker[rr][cc-2]+checker[rr][cc+2]+checker[rr+2][cc]); - //vote2=(checker[rr+1][cc-1]+checker[rr+1][cc+1]+checker[rr-1][cc-1]+checker[rr-1][cc+1]); - //if ((vote1==0 || vote2==0) && (c1+c2)<2*thresh*fabs(d1-d2)) vtest++; - //if (vote1>0 && vote2>0 && (c1+c2)<4*thresh*fabs(d1-d2)) { - if ((c1 + c2) < 4 * thresh * fabs(d1 - d2)) { - //pixel interpolation - float gin = cfa[rr][cc]; + vfloat c1 = (vabsf(o1_1 - o1_2) + vabsf(o1_1 - o1_3) + vabsf(o1_1 - o1_4) + vabsf(o1_2 - o1_3) + vabsf(o1_3 - o1_4) + vabsf(o1_2 - o1_4)); + vfloat c2 = (vabsf(o2_1 - o2_2) + vabsf(o2_1 - o2_3) + vabsf(o2_1 - o2_4) + vabsf(o2_2 - o2_3) + vabsf(o2_3 - o2_4) + vabsf(o2_2 - o2_4)); - float gse = (cfa[rr + 1][cc + 1]) + 0.5f * (cfa[rr][cc] - cfa[rr + 2][cc + 2]); - float gnw = (cfa[rr - 1][cc - 1]) + 0.5f * (cfa[rr][cc] - cfa[rr - 2][cc - 2]); - float gne = (cfa[rr - 1][cc + 1]) + 0.5f * (cfa[rr][cc] - cfa[rr - 2][cc + 2]); - float gsw = (cfa[rr + 1][cc - 1]) + 0.5f * (cfa[rr][cc] - cfa[rr + 2][cc - 2]); + vmask mask1 = vmaskf_lt(c1 + c2, thresh6v * vabsf(d1 - d2)); + if (_mm_movemask_ps((vfloat)mask1)) { // if for any of the 4 pixels the condition is true, do the maths for all 4 pixels and mask the unused out at the end + //pixel interpolation + vfloat gin = LVFU(cfa[rr][cc >> 1]); + vfloat gmp2p2 = gin - LVFU(cfa[rr + 2][(cc >> 1) + 1]); + vfloat gmm2m2 = gin - LVFU(cfa[rr - 2][(cc >> 1) - 1]); + vfloat gmm2p2 = gin - LVFU(cfa[rr - 2][(cc >> 1) + 1]); + vfloat gmp2m2 = gin - LVFU(cfa[rr + 2][(cc >> 1) - 1]); - float wtse = 1.0f / (eps + SQR(cfa[rr + 2][cc + 2] - cfa[rr][cc]) + SQR(cfa[rr + 3][cc + 3] - cfa[rr + 1][cc + 1])); - float wtnw = 1.0f / (eps + SQR(cfa[rr - 2][cc - 2] - cfa[rr][cc]) + SQR(cfa[rr - 3][cc - 3] - cfa[rr - 1][cc - 1])); - float wtne = 1.0f / (eps + SQR(cfa[rr - 2][cc + 2] - cfa[rr][cc]) + SQR(cfa[rr - 3][cc + 3] - cfa[rr - 1][cc + 1])); - float wtsw = 1.0f / (eps + SQR(cfa[rr + 2][cc - 2] - cfa[rr][cc]) + SQR(cfa[rr + 3][cc - 3] - cfa[rr + 1][cc - 1])); + vfloat gse = o1_4 + zd5v * gmp2p2; + vfloat gnw = o1_1 + zd5v * gmm2m2; + vfloat gne = o1_2 + zd5v * gmm2p2; + vfloat gsw = o1_3 + zd5v * gmp2m2; - float ginterp = (gse * wtse + gnw * wtnw + gne * wtne + gsw * wtsw) / (wtse + wtnw + wtne + wtsw); + vfloat wtse = onev / (epsv + SQRV(gmp2p2) + SQRV(LVFU(cfa[rr + 3][(cc + 3) >> 1]) - o1_4)); + vfloat wtnw = onev / (epsv + SQRV(gmm2m2) + SQRV(LVFU(cfa[rr - 3][(cc - 3) >> 1]) - o1_1)); + vfloat wtne = onev / (epsv + SQRV(gmm2p2) + SQRV(LVFU(cfa[rr - 3][(cc + 3) >> 1]) - o1_2)); + vfloat wtsw = onev / (epsv + SQRV(gmp2m2) + SQRV(LVFU(cfa[rr + 3][(cc - 3) >> 1]) - o1_3)); - if ( ((ginterp - gin) < thresh * (ginterp + gin)) ) { - rawData[rr][cc] = 0.5f * (ginterp + gin); - //counter++; + vfloat ginterp = (gse * wtse + gnw * wtnw + gne * wtne + gsw * wtsw) / (wtse + wtnw + wtne + wtsw); + + vfloat val = vself(vmaskf_lt(ginterp - gin, threshv * (ginterp + gin)), zd5v * (ginterp + gin), gin); + val = vself(mask1, val, gin); + STC2VFU(rawData[rr][cc], val); } - } - // } +#endif + + for (; cc < width - 6; cc += 2) { + //neighbour checking code from Manuel Llorens Garcia + float o1_1 = cfa[rr - 1][(cc - 1) >> 1]; + float o1_2 = cfa[rr - 1][(cc + 1) >> 1]; + float o1_3 = cfa[rr + 1][(cc - 1) >> 1]; + float o1_4 = cfa[rr + 1][(cc + 1) >> 1]; + float o2_1 = cfa[rr - 2][cc >> 1]; + float o2_2 = cfa[rr + 2][cc >> 1]; + float o2_3 = cfa[rr][(cc - 2) >> 1]; + float o2_4 = cfa[rr][(cc + 2) >> 1]; + + float d1 = (o1_1 + o1_2) + (o1_3 + o1_4); + float d2 = (o2_1 + o2_2) + (o2_3 + o2_4); + + float c1 = (fabs(o1_1 - o1_2) + fabs(o1_1 - o1_3) + fabs(o1_1 - o1_4) + fabs(o1_2 - o1_3) + fabs(o1_3 - o1_4) + fabs(o1_2 - o1_4)); + float c2 = (fabs(o2_1 - o2_2) + fabs(o2_1 - o2_3) + fabs(o2_1 - o2_4) + fabs(o2_2 - o2_3) + fabs(o2_3 - o2_4) + fabs(o2_2 - o2_4)); + + if (c1 + c2 < thresh6 * fabs(d1 - d2)) { + //pixel interpolation + float gin = cfa[rr][cc >> 1]; + + float gmp2p2 = gin - cfa[rr + 2][(cc + 2) >> 1]; + float gmm2m2 = gin - cfa[rr - 2][(cc - 2) >> 1]; + float gmm2p2 = gin - cfa[rr - 2][(cc + 2) >> 1]; + float gmp2m2 = gin - cfa[rr + 2][(cc - 2) >> 1]; + + float gse = o1_4 + 0.5f * gmp2p2; + float gnw = o1_1 + 0.5f * gmm2m2; + float gne = o1_2 + 0.5f * gmm2p2; + float gsw = o1_3 + 0.5f * gmp2m2; + + float wtse = 1.f / (eps + SQR(gmp2p2) + SQR(cfa[rr + 3][(cc + 3) >> 1] - o1_4)); + float wtnw = 1.f / (eps + SQR(gmm2m2) + SQR(cfa[rr - 3][(cc - 3) >> 1] - o1_1)); + float wtne = 1.f / (eps + SQR(gmm2p2) + SQR(cfa[rr - 3][(cc + 3) >> 1] - o1_2)); + float wtsw = 1.f / (eps + SQR(gmp2m2) + SQR(cfa[rr + 3][(cc - 3) >> 1] - o1_3)); + + float ginterp = (gse * wtse + gnw * wtnw + gne * wtne + gsw * wtsw) / (wtse + wtnw + wtne + wtsw); + + if (ginterp - gin < thresh * (ginterp + gin)) { + rawData[rr][cc] = 0.5f * (ginterp + gin); + } + } + } } - - //printf("pixfix count= %d; vtest= %d \n",counter,vtest); - // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - - // done - /*t2 = clock(); - dt = ((double)(t2-t1)) / CLOCKS_PER_SEC; - if (verbose) { - fprintf(stderr,_("elapsed time = %5.3fs\n"),dt); - }*/ - - + } } } - -#undef TS diff --git a/rtengine/iccstore.cc b/rtengine/iccstore.cc index 49ff4790e..891fb1600 100644 --- a/rtengine/iccstore.cc +++ b/rtengine/iccstore.cc @@ -501,7 +501,9 @@ public: ) ||( type==ICCStore::ProfileType::OUTPUT - && (cmsGetDeviceClass(profile.second) == cmsSigDisplayClass || cmsGetDeviceClass(profile.second) == cmsSigOutputClass) + && (cmsGetDeviceClass(profile.second) == cmsSigDisplayClass + || cmsGetDeviceClass(profile.second) == cmsSigInputClass + || cmsGetDeviceClass(profile.second) == cmsSigOutputClass) && cmsGetColorSpace(profile.second) == cmsSigRgbData ) ) { @@ -807,8 +809,8 @@ void rtengine::ICCStore::getGammaArray(const procparams::ColorManagementParams & double ts = icm.slpos; double slope = icm.slpos == 0 ? eps : icm.slpos; - int mode = 0, imax = 0; - Color::calcGamma(pwr, ts, mode, imax, g_a); // call to calcGamma with selected gamma and slope : return parameters for LCMS2 + int mode = 0; + Color::calcGamma(pwr, ts, mode, g_a); // call to calcGamma with selected gamma and slope : return parameters for LCMS2 ga[4] = g_a[3] * ts; //printf("g_a.gamma0=%f g_a.gamma1=%f g_a.gamma2=%f g_a.gamma3=%f g_a.gamma4=%f\n", g_a.gamma0,g_a.gamma1,g_a.gamma2,g_a.gamma3,g_a.gamma4); ga[0] = icm.gampos; diff --git a/rtengine/icons.cc b/rtengine/icons.cc index 2c5075007..aa3b67cbf 100644 --- a/rtengine/icons.cc +++ b/rtengine/icons.cc @@ -86,7 +86,7 @@ Glib::ustring findIconAbsolutePath (const Glib::ustring& iconName) return Glib::ustring(); } -void setPaths (const Options& options) +void setPaths () { // TODO: Forcing the Dark theme, so reading the icon set files is useless for now... diff --git a/rtengine/icons.h b/rtengine/icons.h index 9f6654a9c..a890555b2 100644 --- a/rtengine/icons.h +++ b/rtengine/icons.h @@ -26,7 +26,7 @@ namespace rtengine { Glib::ustring findIconAbsolutePath (const Glib::ustring& iconName); -void setPaths (const Options& options); +void setPaths (); } diff --git a/rtengine/iimage.h b/rtengine/iimage.h index bae1e3cda..a22630301 100644 --- a/rtengine/iimage.h +++ b/rtengine/iimage.h @@ -28,6 +28,7 @@ #include "coord2d.h" #include "procparams.h" #include "color.h" +#include "../rtgui/threadutils.h" #define TR_NONE 0 #define TR_R90 1 @@ -1803,7 +1804,7 @@ public: * @param compression is the amount of compression (0-6), -1 corresponds to the default * @param bps can be 8 or 16 depending on the bits per pixels the output file will have @return the error code, 0 if none */ - virtual int saveAsPNG (Glib::ustring fname, int compression = -1, int bps = -1) = 0; + virtual int saveAsPNG (Glib::ustring fname, int bps = -1) = 0; /** @brief Saves the image to file in a jpg format. * @param fname is the name of the file * @param quality is the quality of the jpeg (0...100), set it to -1 to use default diff --git a/rtengine/image16.h b/rtengine/image16.h index a220fe221..861a5d8fc 100644 --- a/rtengine/image16.h +++ b/rtengine/image16.h @@ -76,9 +76,9 @@ public: { return save (fname); } - virtual int saveAsPNG (Glib::ustring fname, int compression = -1, int bps = -1) + virtual int saveAsPNG (Glib::ustring fname, int bps = -1) { - return savePNG (fname, compression, bps); + return savePNG (fname, bps); } virtual int saveAsJPEG (Glib::ustring fname, int quality = 100, int subSamp = 3) { diff --git a/rtengine/image8.h b/rtengine/image8.h index 49b98ccd2..02fda32fb 100644 --- a/rtengine/image8.h +++ b/rtengine/image8.h @@ -70,9 +70,9 @@ public: { return save (fname); } - virtual int saveAsPNG (Glib::ustring fname, int compression = -1, int bps = -1) + virtual int saveAsPNG (Glib::ustring fname, int bps = -1) { - return savePNG (fname, compression, bps); + return savePNG (fname, bps); } virtual int saveAsJPEG (Glib::ustring fname, int quality = 100, int subSamp = 3) { diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 5faa6175e..47688fca6 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -18,9 +18,14 @@ */ #include #include +#include #include "imagedata.h" #include "iptcpairs.h" +#include "imagesource.h" +#include "rt_math.h" +#pragma GCC diagnostic warning "-Wextra" +#define PRINT_HDR_PS_DETECTION 0 using namespace rtengine; @@ -40,87 +45,25 @@ Glib::ustring to_utf8 (const std::string& str) } -ImageMetaData* ImageMetaData::fromFile (const Glib::ustring& fname, RawMetaDataLocation* rml) +FramesMetaData* FramesMetaData::fromFile (const Glib::ustring& fname, std::unique_ptr rml, bool firstFrameOnly) { - - return new ImageData (fname, rml); + return new FramesData (fname, std::move(rml), firstFrameOnly); } -ImageData::ImageData (Glib::ustring fname, RawMetaDataLocation* ri) : iso_speed(0), aperture(0.), shutter(0.) +FrameData::FrameData (rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory* rootDir, rtexif::TagDirectory* firstRootDir) + : frameRootDir(frameRootDir_), iptc(nullptr), time(), timeStamp(), iso_speed(0), aperture(0.), focal_len(0.), focal_len35mm(0.), focus_dist(0.f), + shutter(0.), expcomp(0.), make("Unknown"), model("Unknown"), orientation("Unknown"), lens("Unknown"), + sampleFormat(IIOSF_UNKNOWN), isPixelShift(false), isHDR(false) { memset (&time, 0, sizeof(time)); - root = nullptr; - iptc = nullptr; - if (ri && (ri->exifBase >= 0 || ri->ciffBase >= 0)) { - FILE* f = g_fopen (fname.c_str (), "rb"); - - if (f) { - if (ri->exifBase >= 0) { - root = rtexif::ExifManager::parse (f, ri->exifBase); - - if (root) { - rtexif::Tag* t = root->getTag (0x83BB); - - if (t) { - iptc = iptc_data_new_from_data ((unsigned char*)t->getValue (), (unsigned)t->getValueSize ()); - } - } - } else if (ri->ciffBase >= 0) { - root = rtexif::ExifManager::parseCIFF (f, ri->ciffBase, ri->ciffLength); - } - - fclose (f); - extractInfo (); - } - } else if (hasJpegExtension(fname)) { - FILE* f = g_fopen (fname.c_str (), "rb"); - - if (f) { - root = rtexif::ExifManager::parseJPEG (f); - extractInfo (); - fclose (f); - FILE* ff = g_fopen (fname.c_str (), "rb"); - iptc = iptc_data_new_from_jpeg_file (ff); - fclose (ff); - } - } else if (hasTiffExtension(fname)) { - FILE* f = g_fopen (fname.c_str (), "rb"); - - if (f) { - root = rtexif::ExifManager::parseTIFF (f); - fclose (f); - extractInfo (); - - if (root) { - rtexif::Tag* t = root->getTag (0x83BB); - - if (t) { - iptc = iptc_data_new_from_data ((unsigned char*)t->getValue (), (unsigned)t->getValueSize ()); - } - } - } - } else { - root = new rtexif::TagDirectory (); - shutter = 0; - aperture = 0; - iso_speed = 0; - lens = "Unknown"; - make = "Unknown"; - model = "Unknown"; - orientation = "Unknown"; - expcomp = 0; - focal_len = 0; - } -} - -void ImageData::extractInfo () -{ - - if (!root) { + if (!frameRootDir) { return; } + rtexif::Tag* tag; + rtexif::TagDirectory* newFrameRootDir = frameRootDir; + memset(&time, 0, sizeof(time)); timeStamp = 0; iso_speed = 0; @@ -136,8 +79,18 @@ void ImageData::extractInfo () orientation.clear(); lens.clear(); - if (root->getTag("Make")) { - make = root->getTag ("Make")->valueToString(); + tag = newFrameRootDir->findTag("Make"); + if (!tag) { + newFrameRootDir = rootDir; + tag = newFrameRootDir->findTag("Make"); + if (!tag) { + // For some raw files (like Canon's CR2 files), the metadata are contained in the first root directory + newFrameRootDir = firstRootDir; + tag = newFrameRootDir->findTag("Make"); + } + } + if (tag) { + make = tag->valueToString(); // Same dcraw treatment for (const auto& corp : { "Canon", @@ -169,8 +122,9 @@ void ImageData::extractInfo () make.erase(make.find_last_not_of(' ') + 1); } - if (root->getTag("Model")) { - model = root->getTag("Model")->valueToString(); + tag = newFrameRootDir->findTagUpward("Model"); + if (tag) { + model = tag->valueToString(); } if (!model.empty()) { @@ -202,61 +156,68 @@ void ImageData::extractInfo () model = "Unknown"; } - if (root->getTag ("Orientation")) { - orientation = root->getTag ("Orientation")->valueToString (); + tag = newFrameRootDir->findTagUpward("Orientation"); + if (tag) { + orientation = tag->valueToString (); + } + + tag = newFrameRootDir->findTagUpward("MakerNote"); + rtexif::TagDirectory* mnote = nullptr; + if (tag) { + mnote = tag->getDirectory(); } rtexif::TagDirectory* exif = nullptr; - - if (root->getTag ("Exif")) { - exif = root->getTag ("Exif")->getDirectory (); + tag = newFrameRootDir->findTagUpward("Exif"); + if (tag) { + exif = tag->getDirectory (); } if (exif) { // standard exif tags - if (exif->getTag ("ShutterSpeedValue")) { - shutter = exif->getTag ("ShutterSpeedValue")->toDouble (); + if ((tag = exif->getTag ("ShutterSpeedValue"))) { + shutter = tag->toDouble (); } - if (exif->getTag ("ExposureTime")) { - shutter = exif->getTag ("ExposureTime")->toDouble (); + if ((tag = exif->getTag ("ExposureTime"))) { + shutter = tag->toDouble (); } - if (exif->getTag ("ApertureValue")) { - aperture = exif->getTag ("ApertureValue")->toDouble (); + if ((tag = exif->getTag ("ApertureValue"))) { + aperture = tag->toDouble (); } - if (exif->getTag ("FNumber")) { - aperture = exif->getTag ("FNumber")->toDouble (); + if ((tag = exif->getTag ("FNumber"))) { + aperture = tag->toDouble (); } - if (exif->getTag ("ExposureBiasValue")) { - expcomp = exif->getTag ("ExposureBiasValue")->toDouble (); + if ((tag = exif->getTag ("ExposureBiasValue"))) { + expcomp = tag->toDouble (); } - if (exif->getTag ("FocalLength")) { - focal_len = exif->getTag ("FocalLength")->toDouble (); + if ((tag = exif->getTag ("FocalLength"))) { + focal_len = tag->toDouble (); } - if (exif->getTag ("FocalLengthIn35mmFilm")) { - focal_len35mm = exif->getTag ("FocalLengthIn35mmFilm")->toDouble (); + if ((tag = exif->getTag ("FocalLengthIn35mmFilm"))) { + focal_len35mm = tag->toDouble (); } // Focus distance from EXIF or XMP. MakerNote ones are scattered and partly encrypted int num = -3, denom = -3; // First try, offical EXIF. Set by Adobe on some DNGs - rtexif::Tag* pDst = exif->getTag("SubjectDistance"); + tag = exif->getTag("SubjectDistance"); - if (pDst) { + if (tag) { int num, denom; - pDst->toRational(num, denom); + tag->toRational(num, denom); } else { // Second try, XMP data char sXMPVal[64]; - if (root->getXMPTagValue("aux:ApproximateFocusDistance", sXMPVal)) { + if (newFrameRootDir->getXMPTagValue("aux:ApproximateFocusDistance", sXMPVal)) { sscanf(sXMPVal, "%d/%d", &num, &denom); } } @@ -269,12 +230,12 @@ void ImageData::extractInfo () } } - if (exif->getTag ("ISOSpeedRatings")) { - iso_speed = exif->getTag ("ISOSpeedRatings")->toDouble (); + if ((tag = exif->getTag ("ISOSpeedRatings"))) { + iso_speed = tag->toDouble (); } - if (exif->getTag ("DateTimeOriginal")) { - if (sscanf ((const char*)exif->getTag("DateTimeOriginal")->getValue(), "%d:%d:%d %d:%d:%d", &time.tm_year, &time.tm_mon, &time.tm_mday, &time.tm_hour, &time.tm_min, &time.tm_sec) == 6) { + if ((tag = exif->getTag ("DateTimeOriginal"))) { + if (sscanf ((const char*)tag->getValue(), "%d:%d:%d %d:%d:%d", &time.tm_year, &time.tm_mon, &time.tm_mday, &time.tm_hour, &time.tm_min, &time.tm_sec) == 6) { time.tm_year -= 1900; time.tm_mon -= 1; time.tm_isdst = -1; @@ -282,14 +243,14 @@ void ImageData::extractInfo () } } - rtexif::Tag *snTag = exif->findTag ("SerialNumber"); + tag = exif->findTag ("SerialNumber"); - if(!snTag) { - snTag = exif->findTag ("InternalSerialNumber"); + if(!tag) { + tag = exif->findTag ("InternalSerialNumber"); } - if ( snTag ) { - serial = snTag->valueToString(); + if (tag) { + serial = tag->valueToString(); } // guess lens... @@ -313,12 +274,10 @@ void ImageData::extractInfo () } if (lens == "Unknown") { - rtexif::Tag* mnoteTag = root->findTag("MakerNote"); - if (mnoteTag) { - rtexif::TagDirectory* mnote = mnoteTag->getDirectory(); + if (mnote) { - if (mnote && !make.compare (0, 5, "NIKON")) { + if (!make.compare (0, 5, "NIKON")) { // ISO at max value supported, check manufacturer specific if (iso_speed == 65535 || iso_speed == 0) { rtexif::Tag* isoTag = mnote->getTagP("ISOInfo/ISO"); @@ -406,7 +365,7 @@ void ImageData::extractInfo () } } } - } else if (mnote && !make.compare (0, 5, "Canon")) { + } else if (!make.compare (0, 5, "Canon")) { // ISO at max value supported, check manufacturer specific if (iso_speed == 65535 || iso_speed == 0) { rtexif::Tag* baseIsoTag = mnote->getTagP("CanonShotInfo/BaseISO"); @@ -440,7 +399,7 @@ void ImageData::extractInfo () } } } - } else if (mnote && (!make.compare (0, 6, "PENTAX") || (!make.compare (0, 5, "RICOH") && !model.compare (0, 6, "PENTAX")))) { + } else if (!make.compare (0, 6, "PENTAX") || (!make.compare (0, 5, "RICOH") && !model.compare (0, 6, "PENTAX"))) { // ISO at max value supported, check manufacturer specific if (iso_speed == 65535 || iso_speed == 0) { rtexif::Tag* baseIsoTag = mnote->getTag("ISO"); @@ -475,7 +434,7 @@ void ImageData::extractInfo () if (mnote->getTag ("LensID")) { lens = mnote->getTag ("LensID")->valueToString (); } - } else if (mnote && !make.compare (0, 7, "OLYMPUS")) { + } else if (!make.compare (0, 7, "OLYMPUS")) { if (mnote->getTag ("Equipment")) { rtexif::TagDirectory* eq = mnote->getTag ("Equipment")->getDirectory (); @@ -504,31 +463,168 @@ void ImageData::extractInfo () } } } + + rtexif::Tag* t = newFrameRootDir->getTag(0x83BB); + if (t) { + iptc = iptc_data_new_from_data ((unsigned char*)t->getValue (), (unsigned)t->getValueSize ()); + } + + + // ----------------------- Special file type detection (HDR, PixelShift) ------------------------ + + + uint16 bitspersample = 0, sampleformat = 0, photometric = 0, compression = 0; + rtexif::Tag* bps = frameRootDir->findTag("BitsPerSample"); + rtexif::Tag* spp = frameRootDir->findTag("SamplesPerPixel"); + rtexif::Tag* sf = frameRootDir->findTag("SampleFormat"); + rtexif::Tag* pi = frameRootDir->findTag("PhotometricInterpretation"); + rtexif::Tag* c = frameRootDir->findTag("Compression"); + + if (mnote && (!make.compare (0, 6, "PENTAX") || (!make.compare (0, 5, "RICOH") && !model.compare (0, 6, "PENTAX")))) { + rtexif::Tag* hdr = mnote->findTag("HDR"); + if (hdr) { + if (hdr->toInt() > 0 && hdr->toInt(2) > 0) { + isHDR = true; +#if PRINT_HDR_PS_DETECTION + printf("HDR detected ! -> \"HDR\" tag found\n"); +#endif + } + } else { + rtexif::Tag* dm = mnote->findTag("DriveMode"); + if (dm) { + char buffer[60]; + dm->toString(buffer, 3); + buffer[3] = 0; + if (!strcmp(buffer, "HDR")) { + isHDR = true; +#if PRINT_HDR_PS_DETECTION + printf("HDR detected ! -> DriveMode = \"HDR\"\n"); +#endif + } + } + } + + if (!isHDR) { + rtexif::Tag* q = mnote->findTag("Quality"); + if (q && q->toInt() == 7) { + isPixelShift = true; +#if PRINT_HDR_PS_DETECTION + printf("PixelShift detected ! -> \"Quality\" = 7\n"); +#endif + } + } + } + + sampleFormat = IIOSF_UNKNOWN; + + if (!sf) + /* + * WARNING: This is a dirty hack! + * We assume that files which doesn't contain the TIFFTAG_SAMPLEFORMAT tag + * (which is the case with uncompressed TIFFs produced by RT!) are RGB files, + * but that may be not true. --- Hombre + */ + { + sampleformat = SAMPLEFORMAT_UINT; + } else { + sampleformat = sf->toInt(); + } + + if ((!bps & !spp) || !pi) { + return; + } + + bitspersample = bps->toInt(); + + photometric = pi->toInt(); + if (photometric == PHOTOMETRIC_LOGLUV) { + if (!c) { + compression = COMPRESSION_NONE; + } else { + compression = c->toInt(); + } + } + + if (photometric == PHOTOMETRIC_RGB || photometric == PHOTOMETRIC_MINISBLACK) { + if (sampleformat == SAMPLEFORMAT_INT || sampleformat == SAMPLEFORMAT_UINT) { + if (bitspersample == 8) { + sampleFormat = IIOSF_UNSIGNED_CHAR; + } else if (bitspersample <= 16) { + sampleFormat = IIOSF_UNSIGNED_SHORT; + } + } else if (sampleformat == SAMPLEFORMAT_IEEEFP) { + /* + * Not yet supported + * + if (bitspersample==16) { + sampleFormat = IIOSF_HALF; + isHDR = true; + }*/ + if (bitspersample == 32) { + sampleFormat = IIOSF_FLOAT; + isHDR = true; +#if PRINT_HDR_PS_DETECTION + printf("HDR detected ! -> sampleFormat = %d\n", sampleFormat); +#endif + } + } + } else if (photometric == PHOTOMETRIC_CFA) { + if (sampleformat == SAMPLEFORMAT_IEEEFP) { + sampleFormat = IIOSF_FLOAT; + isHDR = true; +#if PRINT_HDR_PS_DETECTION + printf("HDR detected ! -> sampleFormat = %d\n", sampleFormat); +#endif + } else if (sampleformat == SAMPLEFORMAT_INT || sampleformat == SAMPLEFORMAT_UINT) { + if (bitspersample == 8) { // shouldn't occur... + sampleFormat = IIOSF_UNSIGNED_CHAR; + } else if (bitspersample <= 16) { + sampleFormat = IIOSF_UNSIGNED_SHORT; + } + } + } else if (photometric == PHOTOMETRIC_LOGLUV) { + if (compression == COMPRESSION_SGILOG24) { + sampleFormat = IIOSF_LOGLUV24; + isHDR = true; +#if PRINT_HDR_PS_DETECTION + printf("HDR detected ! -> sampleFormat = %d\n", sampleFormat); +#endif + } else if (compression == COMPRESSION_SGILOG) { + sampleFormat = IIOSF_LOGLUV32; + isHDR = true; +#if PRINT_HDR_PS_DETECTION + printf("HDR detected ! -> sampleFormat = %d\n", sampleFormat); +#endif + } + } } -ImageData::~ImageData () +FrameData::~FrameData () { - delete root; - if (iptc) { iptc_data_free (iptc); } } -const procparams::IPTCPairs ImageData::getIPTCData () const +procparams::IPTCPairs FrameData::getIPTCData () const +{ + return getIPTCData(iptc); +} + +procparams::IPTCPairs FrameData::getIPTCData (IptcData* iptc_) { procparams::IPTCPairs iptcc; - if (!iptc) { + if (!iptc_) { return iptcc; } unsigned char buffer[2100]; for (int i = 0; i < 16; i++) { - IptcDataSet* ds = iptc_data_get_next_dataset (iptc, nullptr, IPTC_RECORD_APP_2, strTags[i].tag); + IptcDataSet* ds = iptc_data_get_next_dataset (iptc_, nullptr, IPTC_RECORD_APP_2, strTags[i].tag); if (ds) { iptc_dataset_get_data (ds, buffer, 2100); @@ -543,7 +639,7 @@ const procparams::IPTCPairs ImageData::getIPTCData () const IptcDataSet* ds = nullptr; std::vector keywords; - while ((ds = iptc_data_get_next_dataset (iptc, ds, IPTC_RECORD_APP_2, IPTC_TAG_KEYWORDS))) { + while ((ds = iptc_data_get_next_dataset (iptc_, ds, IPTC_RECORD_APP_2, IPTC_TAG_KEYWORDS))) { iptc_dataset_get_data (ds, buffer, 2100); keywords.push_back (to_utf8((char*)buffer)); } @@ -552,7 +648,7 @@ const procparams::IPTCPairs ImageData::getIPTCData () const ds = nullptr; std::vector suppCategories; - while ((ds = iptc_data_get_next_dataset (iptc, ds, IPTC_RECORD_APP_2, IPTC_TAG_SUPPL_CATEGORY))) { + while ((ds = iptc_data_get_next_dataset (iptc_, ds, IPTC_RECORD_APP_2, IPTC_TAG_SUPPL_CATEGORY))) { iptc_dataset_get_data (ds, buffer, 2100); suppCategories.push_back (to_utf8((char*)buffer)); iptc_dataset_unref (ds); @@ -562,10 +658,268 @@ const procparams::IPTCPairs ImageData::getIPTCData () const return iptcc; } + +bool FrameData::getPixelShift () const +{ + return isPixelShift; +} +bool FrameData::getHDR () const +{ + return isHDR; +} +IIOSampleFormat FrameData::getSampleFormat () const +{ + return sampleFormat; +} +rtexif::TagDirectory* FrameData::getExifData () const +{ + return frameRootDir; +} +bool FrameData::hasExif () const +{ + return frameRootDir && frameRootDir->getCount(); +} +bool FrameData::hasIPTC () const +{ + return iptc; +} +tm FrameData::getDateTime () const +{ + return time; +} +time_t FrameData::getDateTimeAsTS () const +{ + return timeStamp; +} +int FrameData::getISOSpeed () const +{ + return iso_speed; +} +double FrameData::getFNumber () const +{ + return aperture; +} +double FrameData::getFocalLen () const +{ + return focal_len; +} +double FrameData::getFocalLen35mm () const +{ + return focal_len35mm; +} +float FrameData::getFocusDist () const +{ + return focus_dist; +} +double FrameData::getShutterSpeed () const +{ + return shutter; +} +double FrameData::getExpComp () const +{ + return expcomp; +} +std::string FrameData::getMake () const +{ + return make; +} +std::string FrameData::getModel () const +{ + return model; +} +std::string FrameData::getLens () const +{ + return lens; +} +std::string FrameData::getSerialNumber () const +{ + return serial; +} +std::string FrameData::getOrientation () const +{ + return orientation; +} + + + +void FramesData::setDCRawFrameCount (unsigned int frameCount) +{ + dcrawFrameCount = frameCount; +} + +unsigned int FramesData::getRootCount () const +{ + return roots.size(); +} + +unsigned int FramesData::getFrameCount () const +{ + return dcrawFrameCount ? dcrawFrameCount : frames.size(); +} + +FrameData *FramesData::getFrameData (unsigned int frame) const +{ + return frames.empty() || frame >= frames.size() ? nullptr : frames.at(frame); +} + +bool FramesData::getPixelShift (unsigned int frame) const +{ + // So far only Pentax provide multi-frame HDR file. + // Only the first frame contains the HDR tag + // If more brand have to be supported, this rule may need + // to evolve + + //return frames.at(frame)->getPixelShift (); + return frames.empty() || frame >= frames.size() ? false : frames.at(0)->getPixelShift (); +} +bool FramesData::getHDR (unsigned int frame) const +{ + // So far only Pentax provide multi-frame HDR file. + // Only the first frame contains the HDR tag + // If more brand have to be supported, this rule may need + // to evolve + + //return frames.at(frame)->getHDR (); + return frames.empty() || frame >= frames.size() ? false : frames.at(0)->getHDR (); +} + +IIOSampleFormat FramesData::getSampleFormat (unsigned int frame) const +{ + return frames.empty() || frame >= frames.size() ? IIOSF_UNKNOWN : frames.at(frame)->getSampleFormat (); +} + +rtexif::TagDirectory* FramesData::getFrameExifData (unsigned int frame) const +{ + return frames.empty() || frame >= frames.size() ? nullptr : frames.at(frame)->getExifData (); +} + +rtexif::TagDirectory* FramesData::getBestExifData (ImageSource *imgSource, procparams::RAWParams *rawParams) const +{ + rtexif::TagDirectory *td = nullptr; + if (frames.empty()) { + return nullptr; + } + if (imgSource && rawParams) { + eSensorType sensorType = imgSource->getSensorType(); + unsigned int imgNum = 0; + if (sensorType == ST_BAYER) { + imgNum = rtengine::LIM(rawParams->bayersensor.imageNum, 0, frames.size() - 1); + /* + // might exist someday ? + } else if (sensorType == ST_FUJI_XTRANS) { + imgNum = rtengine::LIM(rawParams->xtranssensor.imageNum, 0, frames.size() - 1); + } else if (sensorType == ST_NONE && !imgSource->isRAW()) { + // standard image multiframe support should come here (when implemented in GUI) + */ + } + + frames[imgNum]->getExifData (); + + td = getFrameExifData (imgNum); + rtexif::Tag* makeTag; + if (td && (makeTag = td->findTag("Make", true))) { + td = makeTag->getParent(); + } else { + td = getRootExifData(0); + } + } + return td; +} + +rtexif::TagDirectory* FramesData::getRootExifData (unsigned int root) const +{ + return roots.empty() || root >= roots.size() ? nullptr : roots.at(root); +} + +procparams::IPTCPairs FramesData::getIPTCData (unsigned int frame) const +{ + if (frame < frames.size() && frames.at(frame)->hasIPTC()) { + return frames.at(frame)->getIPTCData(); + } else { + if (iptc) { + return FrameData::getIPTCData(iptc); + } else { + procparams::IPTCPairs emptyPairs; + return emptyPairs; + } + } +} + +bool FramesData::hasExif (unsigned int frame) const +{ + return frames.empty() || frame >= frames.size() ? false : frames.at(frame)->hasExif (); +} +bool FramesData::hasIPTC (unsigned int frame) const +{ + return frames.empty() || frame >= frames.size() ? false : frames.at(frame)->hasIPTC (); +} + +tm FramesData::getDateTime (unsigned int frame) const +{ + if (frames.empty() || frame >= frames.size() ) { + return {}; + } else { + return frames.at(frame)->getDateTime (); + } +} +time_t FramesData::getDateTimeAsTS(unsigned int frame) const +{ + return frames.empty() || frame >= frames.size() ? 0 : frames.at(frame)->getDateTimeAsTS (); +} +int FramesData::getISOSpeed (unsigned int frame) const +{ + return frames.empty() || frame >= frames.size() ? 0 : frames.at(frame)->getISOSpeed (); +} +double FramesData::getFNumber (unsigned int frame) const +{ + return frames.empty() || frame >= frames.size() ? 0. : frames.at(frame)->getFNumber (); +} +double FramesData::getFocalLen (unsigned int frame) const +{ + return frames.empty() || frame >= frames.size() ? 0. : frames.at(frame)->getFocalLen (); +} +double FramesData::getFocalLen35mm (unsigned int frame) const +{ + return frames.empty() || frame >= frames.size() ? 0. : frames.at(frame)->getFocalLen35mm (); +} +float FramesData::getFocusDist (unsigned int frame) const +{ + return frames.empty() || frame >= frames.size() ? 0.f : frames.at(frame)->getFocusDist (); +} +double FramesData::getShutterSpeed (unsigned int frame) const +{ + return frames.empty() || frame >= frames.size() ? 0. : frames.at(frame)->getShutterSpeed (); +} +double FramesData::getExpComp (unsigned int frame) const +{ + return frames.empty() || frame >= frames.size() ? 0. : frames.at(frame)->getExpComp (); +} +std::string FramesData::getMake (unsigned int frame) const +{ + return frames.empty() || frame >= frames.size() ? std::string() : frames.at(frame)->getMake (); +} +std::string FramesData::getModel (unsigned int frame) const +{ + return frames.empty() || frame >= frames.size() ? std::string() : frames.at(frame)->getModel (); +} +std::string FramesData::getLens (unsigned int frame) const +{ + return frames.empty() || frame >= frames.size() ? std::string() : frames.at(frame)->getLens (); +} +std::string FramesData::getSerialNumber (unsigned int frame) const +{ + return frames.empty() || frame >= frames.size() ? std::string() : frames.at(frame)->getSerialNumber (); +} +std::string FramesData::getOrientation (unsigned int frame) const +{ + return frames.empty() || frame >= frames.size() ? std::string() : frames.at(frame)->getOrientation (); +} + + //------inherited functions--------------// -std::string ImageMetaData::apertureToString (double aperture) +std::string FramesMetaData::apertureToString (double aperture) { char buffer[256]; @@ -573,7 +927,7 @@ std::string ImageMetaData::apertureToString (double aperture) return buffer; } -std::string ImageMetaData::shutterToString (double shutter) +std::string FramesMetaData::shutterToString (double shutter) { char buffer[256]; @@ -587,7 +941,7 @@ std::string ImageMetaData::shutterToString (double shutter) return buffer; } -std::string ImageMetaData::expcompToString (double expcomp, bool maskZeroexpcomp) +std::string FramesMetaData::expcompToString (double expcomp, bool maskZeroexpcomp) { char buffer[256]; @@ -605,7 +959,7 @@ std::string ImageMetaData::expcompToString (double expcomp, bool maskZeroexpcomp } } -double ImageMetaData::shutterFromString (std::string s) +double FramesMetaData::shutterFromString (std::string s) { size_t i = s.find_first_of ('/'); @@ -617,7 +971,7 @@ double ImageMetaData::shutterFromString (std::string s) } } -double ImageMetaData::apertureFromString (std::string s) +double FramesMetaData::apertureFromString (std::string s) { return atof (s.c_str()); @@ -685,3 +1039,99 @@ failure: } } + +FramesData::FramesData (const Glib::ustring& fname, std::unique_ptr rml, bool firstFrameOnly) : + iptc(nullptr), dcrawFrameCount (0) +{ + if (rml && (rml->exifBase >= 0 || rml->ciffBase >= 0)) { + FILE* f = g_fopen (fname.c_str (), "rb"); + + if (f) { + const bool has_rml_exif_base = rml->exifBase >= 0; + rtexif::ExifManager exifManager (f, std::move(rml), firstFrameOnly); + + if (has_rml_exif_base) { + if (exifManager.f && exifManager.rml) { + if (exifManager.rml->exifBase >= 0) { + exifManager.parseRaw (); + + } else if (exifManager.rml->ciffBase >= 0) { + exifManager.parseCIFF (); + } + } + + // copying roots + roots = exifManager.roots; + + // creating FrameData + for (auto currFrame : exifManager.frames) { + FrameData* fd = new FrameData(currFrame, currFrame->getRoot(), roots.at(0)); + + frames.push_back(fd); + } + for (auto currRoot : roots) { + rtexif::Tag* t = currRoot->getTag(0x83BB); + + if (t && !iptc) { + iptc = iptc_data_new_from_data ((unsigned char*)t->getValue (), (unsigned)t->getValueSize ()); + break; + } + } + } + fclose (f); + } + } else if (hasJpegExtension(fname)) { + FILE* f = g_fopen (fname.c_str (), "rb"); + + if (f) { + rtexif::ExifManager exifManager (f, std::move(rml), true); + if (exifManager.f) { + exifManager.parseJPEG (); + roots = exifManager.roots; + for (auto currFrame : exifManager.frames) { + FrameData* fd = new FrameData(currFrame, currFrame->getRoot(), roots.at(0)); + frames.push_back(fd); + } + rewind (exifManager.f); // Not sure this is necessary + iptc = iptc_data_new_from_jpeg_file (exifManager.f); + } + fclose (f); + } + } else if (hasTiffExtension(fname)) { + FILE* f = g_fopen (fname.c_str (), "rb"); + + if (f) { + rtexif::ExifManager exifManager (f, std::move(rml), firstFrameOnly); + + exifManager.parseTIFF(); + roots = exifManager.roots; + + // creating FrameData + for (auto currFrame : exifManager.frames) { + FrameData* fd = new FrameData(currFrame, currFrame->getRoot(), roots.at(0)); + + frames.push_back(fd); + } + for (auto currRoot : roots) { + rtexif::Tag* t = currRoot->getTag(0x83BB); + + if (t && !iptc) { + iptc = iptc_data_new_from_data ((unsigned char*)t->getValue (), (unsigned)t->getValueSize ()); + break; + } + } + fclose (f); + } + } +} + +FramesData::~FramesData () +{ + for (auto currRoot : roots) { + delete currRoot; + } + + if (iptc) { + iptc_data_free (iptc); + } +} diff --git a/rtengine/imagedata.h b/rtengine/imagedata.h index f28a49a2f..b9f955611 100644 --- a/rtengine/imagedata.h +++ b/rtengine/imagedata.h @@ -31,11 +31,11 @@ namespace rtengine { -class ImageData : public ImageMetaData +class FrameData { protected: - rtexif::TagDirectory* root; + rtexif::TagDirectory* frameRootDir; IptcData* iptc; struct tm time; @@ -49,84 +49,84 @@ protected: std::string make, model, serial; std::string orientation; std::string lens; + IIOSampleFormat sampleFormat; - void extractInfo (); + // each frame has the knowledge of "being an" + // or "being part of an" HDR or PS image + bool isPixelShift; + bool isHDR; public: - ImageData (Glib::ustring fname, RawMetaDataLocation* rml = nullptr); - virtual ~ImageData (); + FrameData (rtexif::TagDirectory* frameRootDir, rtexif::TagDirectory* rootDir, rtexif::TagDirectory* firstRootDir); + virtual ~FrameData (); - const rtexif::TagDirectory* getExifData () const - { - return root; - } - const procparams::IPTCPairs getIPTCData () const; - - bool hasExif () const - { - return root && root->getCount(); - } - bool hasIPTC () const - { - return iptc; - } - - struct tm getDateTime () const { - return time; - } - time_t getDateTimeAsTS() const - { - return timeStamp; - } - int getISOSpeed () const - { - return iso_speed; - } - double getFNumber () const - { - return aperture; - } - double getFocalLen () const - { - return focal_len; - } - double getFocalLen35mm () const - { - return focal_len35mm; - } - float getFocusDist () const - { - return focus_dist; - } - double getShutterSpeed () const - { - return shutter; - } - double getExpComp () const - { - return expcomp; - } - std::string getMake () const - { - return make; - } - std::string getModel () const - { - return model; - } - std::string getLens () const - { - return lens; - } - std::string getSerialNumber () const - { - return serial; - } - std::string getOrientation () const - { - return orientation; - } + bool getPixelShift () const; + bool getHDR () const; + IIOSampleFormat getSampleFormat () const; + rtexif::TagDirectory* getExifData () const; + procparams::IPTCPairs getIPTCData () const; + static procparams::IPTCPairs getIPTCData (IptcData* iptc_); + bool hasExif () const; + bool hasIPTC () const; + tm getDateTime () const; + time_t getDateTimeAsTS () const; + int getISOSpeed () const; + double getFNumber () const; + double getFocalLen () const; + double getFocalLen35mm () const; + float getFocusDist () const; + double getShutterSpeed () const; + double getExpComp () const; + std::string getMake () const; + std::string getModel () const; + std::string getLens () const; + std::string getSerialNumber () const; + std::string getOrientation () const; }; + +class FramesData : public FramesMetaData { +private: + // frame's root IFD, can be a file root IFD or a SUB-IFD + std::vector frames; + // root IFD in the file + std::vector roots; + IptcData* iptc; + unsigned int dcrawFrameCount; + +public: + FramesData (const Glib::ustring& fname, std::unique_ptr rml = nullptr, bool firstFrameOnly = false); + ~FramesData (); + + void setDCRawFrameCount (unsigned int frameCount); + unsigned int getRootCount () const; + unsigned int getFrameCount () const; + FrameData *getFrameData (unsigned int frame) const; + bool getPixelShift (unsigned int frame = 0) const; + bool getHDR (unsigned int frame = 0) const; + IIOSampleFormat getSampleFormat (unsigned int frame = 0) const; + rtexif::TagDirectory* getFrameExifData (unsigned int frame = 0) const; + rtexif::TagDirectory* getRootExifData (unsigned int root = 0) const; + rtexif::TagDirectory* getBestExifData (ImageSource *imgSource, procparams::RAWParams *rawParams) const; + procparams::IPTCPairs getIPTCData (unsigned int frame = 0) const; + bool hasExif (unsigned int frame = 0) const; + bool hasIPTC (unsigned int frame = 0) const; + tm getDateTime (unsigned int frame = 0) const; + time_t getDateTimeAsTS (unsigned int frame = 0) const; + int getISOSpeed (unsigned int frame = 0) const; + double getFNumber (unsigned int frame = 0) const; + double getFocalLen (unsigned int frame = 0) const; + double getFocalLen35mm (unsigned int frame = 0) const; + float getFocusDist (unsigned int frame = 0) const; + double getShutterSpeed (unsigned int frame = 0) const; + double getExpComp (unsigned int frame = 0) const; + std::string getMake (unsigned int frame = 0) const; + std::string getModel (unsigned int frame = 0) const; + std::string getLens (unsigned int frame = 0) const; + std::string getSerialNumber (unsigned int frame = 0) const; + std::string getOrientation (unsigned int frame = 0) const; +}; + + } #endif diff --git a/rtengine/imagefloat.h b/rtengine/imagefloat.h index 7aa06d3a3..3c60d10f4 100644 --- a/rtengine/imagefloat.h +++ b/rtengine/imagefloat.h @@ -80,9 +80,9 @@ public: { return save (fname); } - virtual int saveAsPNG (Glib::ustring fname, int compression = -1, int bps = -1) + virtual int saveAsPNG (Glib::ustring fname, int bps = -1) { - return savePNG (fname, compression, bps); + return savePNG (fname, bps); } virtual int saveAsJPEG (Glib::ustring fname, int quality = 100, int subSamp = 3) { diff --git a/rtengine/imageformat.h b/rtengine/imageformat.h new file mode 100644 index 000000000..2c9bb480d --- /dev/null +++ b/rtengine/imageformat.h @@ -0,0 +1,54 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2017 Jean-Christophe Frisch + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#ifndef _IMAGEFORMAT_ +#define _IMAGEFORMAT_ + +namespace rtengine +{ + +//NB: Update the associated strings in languages files when updating the following enum +// Look for "SAMPLEFORMAT_" +typedef enum IIO_Sample_Format { + IIOSF_UNKNOWN = 0, // Unknown or Unsupported file type; Has to remain 0 + //IIOSF_SIGNED_INT , // Not yet supported + IIOSF_UNSIGNED_CHAR = 1 << 0, + IIOSF_UNSIGNED_SHORT = 1 << 1, + //IIOSF_HALF , // OpenEXR & NVidia's Half Float, not yet supported + IIOSF_LOGLUV24 = 1 << 2, + IIOSF_LOGLUV32 = 1 << 3, + IIOSF_FLOAT = 1 << 4 +} IIOSampleFormat; + +typedef enum IIO_Sample_Arrangement { + IIOSA_UNKNOWN, // Unknown or Unsupported file type + IIOSA_CHUNKY, + IIOSA_PLANAR +} IIOSampleArrangement; + +typedef enum SensorType { + ST_NONE, // use this value if the image is already demosaiced (i.e. not a raw file) + ST_BAYER, + ST_FUJI_XTRANS, + ST_FOVEON, + //ST_FUJI_EXR +} eSensorType; + +} + +#endif diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index 01bbddf13..ff9c9b559 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -905,7 +905,7 @@ int ImageIO::loadPPMFromMemory(const char* buffer, int width, int height, bool s return IMIO_SUCCESS; } -int ImageIO::savePNG (Glib::ustring fname, int compression, volatile int bps) +int ImageIO::savePNG (Glib::ustring fname, volatile int bps) { if (getWidth() < 1 || getHeight() < 1) { return IMIO_HEADERERROR; @@ -945,7 +945,9 @@ int ImageIO::savePNG (Glib::ustring fname, int compression, volatile int bps) png_set_write_fn (png, file, png_write_data, png_flush); - png_set_compression_level(png, compression); + png_set_filter(png, 0, PNG_FILTER_PAETH); + png_set_compression_level(png, 6); + png_set_compression_strategy(png, 3); int width = getWidth (); int height = getHeight (); diff --git a/rtengine/imageio.h b/rtengine/imageio.h index f25cb5470..5f24cc1b7 100644 --- a/rtengine/imageio.h +++ b/rtengine/imageio.h @@ -29,6 +29,7 @@ #define IMIO_CANNOTWRITEFILE 7 #include "rtengine.h" +#include "imageformat.h" #include #include "procparams.h" #include @@ -43,31 +44,6 @@ namespace rtengine class ProgressListener; class Imagefloat; -typedef enum IIO_Sample_Format { - IIOSF_UNKNOWN = 0, // Unknown or Unsupported file type; Has to remain 0 - //IIOSF_SIGNED_INT , // Not yet supported - IIOSF_UNSIGNED_CHAR = 1 << 0, - IIOSF_UNSIGNED_SHORT = 1 << 1, - //IIOSF_HALF , // OpenEXR & NVidia's Half Float, not yet supported - IIOSF_LOGLUV24 = 1 << 2, - IIOSF_LOGLUV32 = 1 << 3, - IIOSF_FLOAT = 1 << 4 -} IIOSampleFormat; - -typedef enum IIO_Sample_Arrangement { - IIOSA_UNKNOWN, // Unknown or Unsupported file type - IIOSA_CHUNKY, - IIOSA_PLANAR -} IIOSampleArrangement; - -typedef enum SensorType { - ST_NONE, // use this value if the image is already demosaiced (i.e. not a raw file) - ST_BAYER, - ST_FUJI_XTRANS, - ST_FOVEON, - //ST_FUJI_EXR -} eSensorType; - class ImageIO : virtual public ImageDatas { @@ -160,7 +136,7 @@ public: int loadJPEGFromMemory (const char* buffer, int bufsize); int loadPPMFromMemory(const char* buffer, int width, int height, bool swap, int bps); - int savePNG (Glib::ustring fname, int compression = -1, volatile int bps = -1); + int savePNG (Glib::ustring fname, volatile int bps = -1); int saveJPEG (Glib::ustring fname, int quality = 100, int subSamp = 3); int saveTIFF (Glib::ustring fname, int bps = -1, bool uncompressed = false); diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h index 0eec1325a..b76a962eb 100644 --- a/rtengine/imagesource.h +++ b/rtengine/imagesource.h @@ -57,7 +57,7 @@ protected: double redAWBMul, greenAWBMul, blueAWBMul; // local copy of the multipliers, to avoid recomputing the values cmsHPROFILE embProfile; Glib::ustring fileName; - ImageData* idata; + FramesData* idata; ImageMatrices imatrices; double dirpyrdenoiseExpComp; @@ -66,7 +66,7 @@ public: embProfile(nullptr), idata(nullptr), dirpyrdenoiseExpComp(INFINITY) {} virtual ~ImageSource () {} - virtual int load (const Glib::ustring &fname, int imageNum = 0, bool batch = false) = 0; + virtual int load (const Glib::ustring &fname) = 0; virtual void preprocess (const RAWParams &raw, const LensProfParams &lensProf, const CoarseTransformParams& coarse, bool prepareDenoise = true) {}; virtual void demosaic (const RAWParams &raw) {}; virtual void retinex (ColorManagementParams cmp, const RetinexParams &deh, 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) {}; @@ -76,16 +76,16 @@ public: virtual void flushRGB () {}; virtual void HLRecovery_Global (ToneCurveParams hrp) {}; virtual void HLRecovery_inpaint (float** red, float** green, float** blue) {}; - virtual void MSR(LabImage* lab, LUTf & mapcurve, bool &mapcontlutili, int width, int height, int skip, RetinexParams deh, const RetinextransmissionCurve & dehatransmissionCurve, const RetinexgaintransmissionCurve & dehagaintransmissionCurve, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax) {}; + virtual void MSR (LabImage* lab, LUTf & mapcurve, bool &mapcontlutili, int width, int height, int skip, RetinexParams deh, const RetinextransmissionCurve & dehatransmissionCurve, const RetinexgaintransmissionCurve & dehagaintransmissionCurve, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax) {}; - virtual bool IsrgbSourceModified() const = 0; // tracks whether cached rgb output of demosaic has been modified + virtual bool isRGBSourceModified () const = 0; // tracks whether cached rgb output of demosaic has been modified - virtual void setCurrentFrame(unsigned int frameNum) = 0; - virtual int getFrameCount() = 0; + virtual void setCurrentFrame (unsigned int frameNum) = 0; + virtual int getFrameCount () = 0; // use right after demosaicing image, add coarse transformation and put the result in the provided Imagefloat* - virtual void getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const ToneCurveParams &hlp, const ColorManagementParams &cmp, const RAWParams &raw) = 0; + virtual void getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const ToneCurveParams &hlp, const RAWParams &raw) = 0; virtual eSensorType getSensorType () const = 0; // true is ready to provide the AutoWB, i.e. when the image has been demosaiced for RawImageSource virtual bool isWBProviderReady () = 0; @@ -107,10 +107,10 @@ public: return 0; } - virtual ImageData* getImageData () = 0; + virtual FrameData* getImageData (unsigned int frameNum) = 0; virtual ImageMatrices* getImageMatrices () = 0; - virtual bool isRAW() const = 0; - virtual DCPProfile* getDCP(const ColorManagementParams &cmp, ColorTemp &wb, DCPProfile::ApplyState &as) + virtual bool isRAW () const = 0; + virtual DCPProfile* getDCP (const ColorManagementParams &cmp, DCPProfile::ApplyState &as) { return nullptr; }; @@ -150,7 +150,7 @@ public: { return embProfile; } - virtual const ImageMetaData* getMetaData () + virtual const FramesMetaData* getMetaData () { return idata; } diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index ab35f97c6..fc6a2284f 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -33,7 +33,7 @@ namespace rtengine extern const Settings* settings; ImProcCoordinator::ImProcCoordinator () - : orig_prev (nullptr), oprevi (nullptr), spotprevi (nullptr), oprevl (nullptr), nprevl (nullptr), previmg (nullptr), workimg (nullptr), + : orig_prev (nullptr), oprevi (nullptr), spotprevi (nullptr), oprevl (nullptr), nprevl (nullptr), fattal_11_dcrop_cache(nullptr), previmg (nullptr), workimg (nullptr), ncie (nullptr), imgsrc (nullptr), shmap (nullptr), lastAwbEqual (0.), lastAwbTempBias (0.0), ipf (¶ms, true), previewProps(-1, -1, -1, -1, 1), monitorIntent (RI_RELATIVE), softProof (false), gamutCheck (false), scale (10), highDetailPreprocessComputed (false), highDetailRawComputed (false), allocated (false), bwAutoR (-9000.f), bwAutoG (-9000.f), bwAutoB (-9000.f), CAMMean (NAN), @@ -111,6 +111,10 @@ ImProcCoordinator::~ImProcCoordinator () mProcessing.lock(); mProcessing.unlock(); freeAll (); + if (fattal_11_dcrop_cache) { + delete fattal_11_dcrop_cache; + fattal_11_dcrop_cache = nullptr; + } std::vector toDel = crops; @@ -220,8 +224,8 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) if ( (todo & M_RAW) || (!highDetailRawComputed && highDetailNeeded) - || ( params.toneCurve.hrenabled && params.toneCurve.method != "Color" && imgsrc->IsrgbSourceModified()) - || (!params.toneCurve.hrenabled && params.toneCurve.method == "Color" && imgsrc->IsrgbSourceModified())) { + || ( params.toneCurve.hrenabled && params.toneCurve.method != "Color" && imgsrc->isRGBSourceModified()) + || (!params.toneCurve.hrenabled && params.toneCurve.method == "Color" && imgsrc->isRGBSourceModified())) { if (settings->verbose) { if (imgsrc->getSensorType() == ST_BAYER) { @@ -280,7 +284,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) } } - if (todo & (M_INIT | M_LINDENOISE)) { + if (todo & (M_INIT | M_LINDENOISE | M_HDR)) { MyMutex::MyLock initLock (minit); // Also used in crop window imgsrc->HLRecovery_Global ( params.toneCurve); // this handles Color HLRecovery @@ -333,7 +337,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) // Tells to the ImProcFunctions' tools what is the preview scale, which may lead to some simplifications ipf.setScale (scale); - imgsrc->getImage (currWB, tr, orig_prev, previewProps, params.toneCurve, params.icm, params.raw); + imgsrc->getImage (currWB, tr, orig_prev, previewProps, params.toneCurve, params.raw); denoiseInfoStore.valid = false; //ColorTemp::CAT02 (orig_prev, ¶ms) ; // printf("orig_prevW=%d\n scale=%d",orig_prev->width, scale); @@ -385,72 +389,17 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) readyphase++; - progress ("Rotate / Distortion...", 100 * readyphase / numofphases); - // Remove transformation if unneeded - bool needstransform = ipf.needsTransform(); - - if (!needstransform && ! ((todo & (M_TRANSFORM | M_RGBCURVE)) && params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled && !params.colorappearance.enabled) && orig_prev != oprevi) { - delete oprevi; - spotprevi = oprevi = orig_prev; - } - - if ((needstransform || ((todo & (M_TRANSFORM | M_RGBCURVE)) && params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled && !params.colorappearance.enabled)) ) { - if (!oprevi || oprevi == orig_prev) { - spotprevi = oprevi = new Imagefloat (pW, pH); + if ((todo & M_HDR) && params.fattal.enabled) { + if (fattal_11_dcrop_cache) { + delete fattal_11_dcrop_cache; + fattal_11_dcrop_cache = nullptr; } - - if (needstransform) - ipf.transform (orig_prev, oprevi, 0, 0, 0, 0, pW, pH, fw, fh, imgsrc->getMetaData()->getFocalLen(), - imgsrc->getMetaData()->getFocalLen35mm(), imgsrc->getMetaData()->getFocusDist(), imgsrc->getMetaData()->getFNumber(), imgsrc->getRotateDegree(), false); - else { - orig_prev->copyData (oprevi); - } - } - - if ((todo & (M_TRANSFORM | M_RGBCURVE)) && params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled && !params.colorappearance.enabled) { - const int W = oprevi->getWidth(); - const int H = oprevi->getHeight(); - LabImage labcbdl (W, H); - ipf.rgb2lab (*oprevi, labcbdl, params.icm.working); - ipf.dirpyrequalizer (&labcbdl, scale); - ipf.lab2rgb (labcbdl, *oprevi, params.icm.working); - } - - readyphase++; - progress ("Preparing shadow/highlight map...", 100 * readyphase / numofphases); - - if ((todo & M_BLURMAP) && params.sh.enabled) { - double radius = sqrt (double (pW * pW + pH * pH)) / 2.0; - double shradius = params.sh.radius; - - if (!params.sh.hq) { - shradius *= radius / 1800.0; - } - - if (!shmap) { - shmap = new SHMap (pW, pH, true); - } - - shmap->update (oprevi, shradius, ipf.lumimul, params.sh.hq, scale); - } - - - - readyphase++; - - if (todo & M_AUTOEXP) { - if (params.toneCurve.autoexp) { - LUTu aehist; - int aehistcompr; - imgsrc->getAutoExpHistogram (aehist, aehistcompr); - ipf.getAutoExp (aehist, aehistcompr, imgsrc->getDefGain(), params.toneCurve.clip, params.toneCurve.expcomp, - params.toneCurve.brightness, params.toneCurve.contrast, params.toneCurve.black, params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh); - - if (aeListener) - aeListener->autoExpChanged (params.toneCurve.expcomp, params.toneCurve.brightness, params.toneCurve.contrast, - params.toneCurve.black, params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh, params.toneCurve.hrenabled); + ipf.ToneMapFattal02(orig_prev); + if (oprevi != orig_prev) { + delete oprevi; } } + oprevi = orig_prev; progress ("Spot Removal...", 100 * readyphase / numofphases); @@ -470,16 +419,78 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) readyphase++; + progress ("Rotate / Distortion...", 100 * readyphase / numofphases); + // Remove transformation if unneeded + bool needstransform = ipf.needsTransform(); + + if ((needstransform || ((todo & (M_TRANSFORM | M_RGBCURVE)) && params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled && !params.colorappearance.enabled)) ) { + assert(spotprevi); + Imagefloat *op = spotprevi; + spotprevi = new Imagefloat (pW, pH); + + if (needstransform) + ipf.transform (op, spotprevi, 0, 0, 0, 0, pW, pH, fw, fh, + imgsrc->getMetaData(), imgsrc->getRotateDegree(), false); + else { + op->copyData (spotprevi); + } + } + + if ((todo & (M_TRANSFORM | M_RGBCURVE)) && params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled && !params.colorappearance.enabled) { + const int W = spotprevi->getWidth(); + const int H = spotprevi->getHeight(); + LabImage labcbdl (W, H); + ipf.rgb2lab (*spotprevi, labcbdl, params.icm.working); + ipf.dirpyrequalizer (&labcbdl, scale); + ipf.lab2rgb (labcbdl, *spotprevi, params.icm.working); + } + + readyphase++; + progress ("Preparing shadow/highlight map...", 100 * readyphase / numofphases); + + if ((todo & M_BLURMAP) && params.sh.enabled) { + double radius = sqrt (double (pW * pW + pH * pH)) / 2.0; + double shradius = params.sh.radius; + + if (!params.sh.hq) { + shradius *= radius / 1800.0; + } + + if (!shmap) { + shmap = new SHMap (pW, pH, true); + } + + shmap->update (spotprevi, shradius, ipf.lumimul, params.sh.hq, scale); + } + + + + readyphase++; + + if (todo & M_AUTOEXP) { + if (params.toneCurve.autoexp) { + LUTu aehist; + int aehistcompr; + imgsrc->getAutoExpHistogram (aehist, aehistcompr); + ipf.getAutoExp (aehist, aehistcompr, params.toneCurve.clip, params.toneCurve.expcomp, + params.toneCurve.brightness, params.toneCurve.contrast, params.toneCurve.black, params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh); + + if (aeListener) + aeListener->autoExpChanged (params.toneCurve.expcomp, params.toneCurve.brightness, params.toneCurve.contrast, + params.toneCurve.black, params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh, params.toneCurve.hrenabled); + } + } + progress ("Exposure curve & CIELAB conversion...", 100 * readyphase / numofphases); if ((todo & M_RGBCURVE) || (todo & M_CROP)) { -// if (hListener) oprevi->calcCroppedHistogram(params, scale, histCropped); +// if (hListener) spotprevi->calcCroppedHistogram(params, scale, histCropped); //complexCurve also calculated pre-curves histogram depending on crop CurveFactory::complexCurve (params.toneCurve.expcomp, params.toneCurve.black / 65535.0, params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh, params.toneCurve.shcompr, params.toneCurve.brightness, params.toneCurve.contrast, - params.toneCurve.curveMode, params.toneCurve.curve, params.toneCurve.curveMode2, params.toneCurve.curve2, + params.toneCurve.curve, params.toneCurve.curve2, vhist16, hltonecurve, shtonecurve, tonecurve, histToneCurve, customToneCurve1, customToneCurve2, 1); CurveFactory::RGBCurve (params.rgbCurves.rcurve, rCurve, 1); @@ -496,13 +507,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {wprof[1][0], wprof[1][1], wprof[1][2]}, {wprof[2][0], wprof[2][1], wprof[2][2]} }; - TMatrix wiprof = ICCStore::getInstance()->workingSpaceInverseMatrix (params.icm.working); - 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]} - }; - params.colorToning.getCurves (ctColorCurve, ctOpacityCurve, wp, wip, opautili); + params.colorToning.getCurves (ctColorCurve, ctOpacityCurve, wp, opautili); CurveFactory::curveToning (params.colorToning.clcurve, clToningcurve, scale == 1 ? 1 : 16); CurveFactory::curveToning (params.colorToning.cl2curve, cl2Toningcurve, scale == 1 ? 1 : 16); } @@ -574,7 +579,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) double bbm = 33.; DCPProfile::ApplyState as; - DCPProfile *dcpProf = imgsrc->getDCP (params.icm, currWB, as); + DCPProfile *dcpProf = imgsrc->getDCP (params.icm, as); ipf.rgbProc (spotprevi, oprevl, nullptr, hltonecurve, shtonecurve, tonecurve, shmap, params.toneCurve.saturation, rCurve, gCurve, bCurve, colourToningSatLimit, colourToningSatLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, clToningcurve, cl2Toningcurve, customToneCurve1, customToneCurve2, beforeToneCurveBW, afterToneCurveBW, rrm, ggm, bbm, bwAutoR, bwAutoG, bwAutoB, params.toneCurve.expcomp, params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh, dcpProf, as, histToneCurve); @@ -724,7 +729,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) int kall = 0; progress ("Wavelet...", 100 * readyphase / numofphases); // ipf.ip_wavelet(nprevl, nprevl, kall, WaveParams, wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, scale); - ipf.ip_wavelet (nprevl, nprevl, kall, WaveParams, wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, wavcontlutili, scale); + ipf.ip_wavelet (nprevl, nprevl, kall, WaveParams, wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, scale); } @@ -750,10 +755,21 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) CurveFactory::curveLightBrightColor (params.colorappearance.curve, params.colorappearance.curve2, params.colorappearance.curve3, lhist16CAM, histLCAM, lhist16CCAM, histCCAM, customColCurve1, customColCurve2, customColCurve3, 1); - float fnum = imgsrc->getMetaData()->getFNumber (); // F number - float fiso = imgsrc->getMetaData()->getISOSpeed () ; // ISO - float fspeed = imgsrc->getMetaData()->getShutterSpeed () ; // Speed - double fcomp = imgsrc->getMetaData()->getExpComp (); // Compensation +/- + + const FramesMetaData* metaData = imgsrc->getMetaData(); + int imgNum = 0; + if (imgsrc->isRAW()) { + if (imgsrc->getSensorType() == ST_BAYER) { + imgNum = rtengine::LIM(params.raw.bayersensor.imageNum, 0, metaData->getFrameCount() - 1); + } else if (imgsrc->getSensorType() == ST_FUJI_XTRANS) { + //imgNum = rtengine::LIM(params.raw.xtranssensor.imageNum, 0, metaData->getFrameCount() - 1); + } + } + + float fnum = metaData->getFNumber (imgNum); // F number + float fiso = metaData->getISOSpeed (imgNum) ; // ISO + float fspeed = metaData->getShutterSpeed (imgNum) ; // Speed + double fcomp = metaData->getExpComp (imgNum); // Compensation +/- double adap; if (fnum < 0.3f || fiso < 5.f || fspeed < 0.00001f) { //if no exif data or wrong @@ -766,8 +782,6 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) // end calculation adaptation scene luminosity } - int begh = 0; - int endh = pH; float d, dj, yb; bool execsharp = false; @@ -788,7 +802,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) CAMBrightCurveJ.dirty = true; CAMBrightCurveQ.dirty = true; - ipf.ciecam_02float (ncie, float (adap), begh, endh, pW, 2, nprevl, ¶ms, customColCurve1, customColCurve2, customColCurve3, histLCAM, histCCAM, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, scale, execsharp, d, dj, yb, 1); + ipf.ciecam_02float (ncie, float (adap), pW, 2, nprevl, ¶ms, customColCurve1, customColCurve2, customColCurve3, histLCAM, histCCAM, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, scale, execsharp, d, dj, yb, 1); if ((params.colorappearance.autodegree || params.colorappearance.autodegreeout) && acListener && params.colorappearance.enabled) { acListener->autoCamChanged (100.* (double)d, 100.* (double)dj); @@ -1141,10 +1155,10 @@ void ImProcCoordinator::getAutoCrop (double ratio, int &x, int &y, int &w, int & MyMutex::MyLock lock (mProcessing); - LCPMapper *pLCPMap = nullptr; + LensCorrection *pLCPMap = nullptr; - if (params.lensProf.lcpFile.length() && imgsrc->getMetaData()->getFocalLen() > 0) { - LCPProfile *pLCPProf = lcpStore->getProfile (params.lensProf.lcpFile); + if (params.lensProf.useLcp() && imgsrc->getMetaData()->getFocalLen() > 0) { + const std::shared_ptr pLCPProf = LCPStore::getInstance()->getProfile (params.lensProf.lcpFile); if (pLCPProf) pLCPMap = new LCPMapper (pLCPProf, imgsrc->getMetaData()->getFocalLen(), imgsrc->getMetaData()->getFocalLen35mm(), imgsrc->getMetaData()->getFocusDist(), 0, false, params.lensProf.useDist, fullw, fullh, params.coarse, imgsrc->getRotateDegree()); @@ -1237,13 +1251,13 @@ void ImProcCoordinator::saveInputICCReference (const Glib::ustring& fname, bool currWB = ColorTemp(); // = no white balance } - imgsrc->getImage (currWB, tr, im, pp, ppar.toneCurve, ppar.icm, ppar.raw); + imgsrc->getImage (currWB, tr, im, pp, ppar.toneCurve, ppar.raw); ImProcFunctions ipf (&ppar, true); if (ipf.needsTransform()) { Imagefloat* trImg = new Imagefloat (fW, fH); - ipf.transform (im, trImg, 0, 0, 0, 0, fW, fH, fW, fH, imgsrc->getMetaData()->getFocalLen(), imgsrc->getMetaData()->getFocalLen35mm(), - imgsrc->getMetaData()->getFocusDist(), imgsrc->getMetaData()->getFNumber(), imgsrc->getRotateDegree(), true); + ipf.transform (im, trImg, 0, 0, 0, 0, fW, fH, fW, fH, + imgsrc->getMetaData(), imgsrc->getRotateDegree(), true); delete im; im = trImg; } diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index 9c1c0c9a2..250e30c1c 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -58,6 +58,7 @@ protected: Imagefloat *spotprevi; LabImage *oprevl; LabImage *nprevl; + Imagefloat *fattal_11_dcrop_cache; // global cache for ToneMapFattal02 used in 1:1 detail windows (except when denoise is active) Image8 *previmg; // displayed image in monitor color space, showing the output profile as well (soft-proofing enabled, which then correspond to workimg) or not Image8 *workimg; // internal image in output color space for analysis CieImage *ncie; diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 6d6fccc88..c22d7b509 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -28,7 +28,6 @@ #include "curves.h" #include "mytime.h" #include "iccstore.h" -#include "impulse_denoise.h" #include "imagesource.h" #include "rtthumbnail.h" #include "utils.h" @@ -208,9 +207,9 @@ void ImProcFunctions::firstAnalysis (const Imagefloat* const original, const Pro } // Copyright (c) 2012 Jacques Desmis -void ImProcFunctions::ciecam_02 (CieImage* ncie, double adap, int begh, int endh, int pW, int pwb, LabImage* lab, const ProcParams* params, +void ImProcFunctions::ciecam_02 (CieImage* ncie, double adap, int pW, int pwb, LabImage* lab, const ProcParams* params, const ColorAppearance & customColCurve1, const ColorAppearance & customColCurve2, const ColorAppearance & customColCurve3, - LUTu & histLCAM, LUTu & histCCAM, LUTf & CAMBrightCurveJ, LUTf & CAMBrightCurveQ, float &mean, int Iterates, int scale, bool execsharp, double &d, double &dj, double &yb, int rtt) + LUTu & histLCAM, LUTu & histCCAM, LUTf & CAMBrightCurveJ, LUTf & CAMBrightCurveQ, float &mean, int Iterates, int scale, bool execsharp, double &d, double &dj, int rtt) { if (params->colorappearance.enabled) { //int lastskip; @@ -256,7 +255,6 @@ void ImProcFunctions::ciecam_02 (CieImage* ncie, double adap, int begh, int endh int width = lab->W, height = lab->H; float minQ = 10000.f; float maxQ = -1000.f; - float w_h; float a_w; float c_; float f_l; @@ -276,9 +274,9 @@ void ImProcFunctions::ciecam_02 (CieImage* ncie, double adap, int begh, int endh bool ciedata = params->colorappearance.datacie; - ColorTemp::temp2mulxyz (params->wb.temperature, params->wb.green, params->wb.method, Xw, Zw); //compute white Xw Yw Zw : white current WB - ColorTemp::temp2mulxyz (params->colorappearance.tempout, params->colorappearance.greenout, "Custom", Xwout, Zwout); - ColorTemp::temp2mulxyz (params->colorappearance.tempsc, params->colorappearance.greensc, "Custom", Xwsc, Zwsc); + ColorTemp::temp2mulxyz (params->wb.temperature, params->wb.method, Xw, Zw); //compute white Xw Yw Zw : white current WB + ColorTemp::temp2mulxyz (params->colorappearance.tempout, "Custom", Xwout, Zwout); + ColorTemp::temp2mulxyz (params->colorappearance.tempsc, "Custom", Xwsc, Zwsc); //viewing condition for surrsrc if (params->colorappearance.surrsrc == "Average") { @@ -607,7 +605,7 @@ void ImProcFunctions::ciecam_02 (CieImage* ncie, double adap, int begh, int endh #ifndef _DEBUG - #pragma omp parallel default(shared) firstprivate(lab,xw1,xw2,yw1,yw2,zw1,zw2,pilot,jli,chr,yb,la,yb2,la2,fl,nc,f,c, height,width,begh, endh,nc2,f2,c2, alg,algepd, gamu, highlight, rstprotection, pW, scale) + #pragma omp parallel default(shared) firstprivate(lab,xw1,xw2,yw1,yw2,zw1,zw2,pilot,jli,chr,yb,la,yb2,la2,fl,nc,f,c, height,width,nc2,f2,c2, alg,algepd, gamu, highlight, rstprotection, pW, scale) #endif { //matrix for current working space @@ -653,15 +651,13 @@ void ImProcFunctions::ciecam_02 (CieImage* ncie, double adap, int begh, int endh Q, M, s, aw, fl, wh, x, y, z, xw1, yw1, zw1, - yb, la, - f, c, nc, pilot, gamu, n, nbb, ncb, pfl, cz, d ); + c, nc, gamu, n, nbb, ncb, pfl, cz, d ); Jpro = J; Cpro = C; hpro = h; Qpro = Q; Mpro = M; spro = s; - w_h = wh + epsil; a_w = aw; c_ = c; f_l = fl; @@ -846,6 +842,7 @@ void ImProcFunctions::ciecam_02 (CieImage* ncie, double adap, int begh, int endh } else if (curveMode == ColorAppearanceParams::TC_MODE_BRIGHT) { //attention! Brightness curves are open - unlike Lightness or Lab or RGB==> rendering and algoritms will be different float coef = ((aw + 4.f) * (4.f / c)) / 100.f; + float Qanc = Qpro; float Qq = (float) Qpro * 327.68f * (1.f / coef); float Qold100 = (float) Qpro / coef; @@ -871,8 +868,15 @@ void ImProcFunctions::ciecam_02 (CieImage* ncie, double adap, int begh, int endh Qq = 0.7f * (Qq - Qold) + Qold; // not zero ==>artifacts } - Qpro = (double) (Qq * (coef) / 327.68f); - Jpro = 100.* (Qpro * Qpro) / ((4.0 / c) * (4.0 / c) * (aw + 4.0) * (aw + 4.0)); + if (Qold == 0.f) { + Qold = 0.001f; + } + + Qpro = Qanc * (Qq / Qold); + Jpro = Jpro * SQR (Qq / Qold); + +// Qpro = (double) (Qq * (coef) / 327.68f); +// Jpro = 100.* (Qpro * Qpro) / ((4.0 / c) * (4.0 / c) * (aw + 4.0) * (aw + 4.0)); t1B = true; if (Jpro < 1.) { @@ -927,6 +931,7 @@ void ImProcFunctions::ciecam_02 (CieImage* ncie, double adap, int begh, int endh } } else if (curveMode2 == ColorAppearanceParams::TC_MODE_BRIGHT) { // + float Qanc = Qpro; float coef = ((aw + 4.f) * (4.f / c)) / 100.f; float Qq = (float) Qpro * 327.68f * (1.f / coef); float Qold100 = (float) Qpro / coef; @@ -953,8 +958,16 @@ void ImProcFunctions::ciecam_02 (CieImage* ncie, double adap, int begh, int endh Qq = 0.7f * (Qq - Qold) + Qold; // not zero ==>artifacts } - Qpro = (double) (Qq * (coef) / 327.68f); - Jpro = 100.* (Qpro * Qpro) / ((4.0 / c) * (4.0 / c) * (aw + 4.0) * (aw + 4.0)); + if (Qold == 0.f) { + Qold = 0.001f; + } + + // Qpro = (float) (Qq * (coef) / 327.68f); + Qpro = Qanc * (Qq / Qold); + Jpro = Jpro * SQR (Qq / Qold); + + // Qpro = (double) (Qq * (coef) / 327.68f); + // Jpro = 100.* (Qpro * Qpro) / ((4.0 / c) * (4.0 / c) * (aw + 4.0) * (aw + 4.0)); t2B = true; if (t1L) { //to workaround the problem if we modify curve1-lightnees after curve2 brightness(the cat that bites its own tail!) in fact it's another type of curve only for this case @@ -1163,8 +1176,7 @@ void ImProcFunctions::ciecam_02 (CieImage* ncie, double adap, int begh, int endh Ciecam02::jch2xyz_ciecam02 ( xx, yy, zz, J, C, h, xw2, yw2, zw2, - yb2, la2, - f2, c2, nc2, gamu, nj, nbbj, ncbj, flj, czj, dj, awj); + c2, nc2, gamu, nj, nbbj, ncbj, flj, czj, dj, awj); x = (float)xx * 655.35; y = (float)yy * 655.35; z = (float)zz * 655.35; @@ -1251,11 +1263,6 @@ void ImProcFunctions::ciecam_02 (CieImage* ncie, double adap, int begh, int endh //if(params->dirpyrequalizer.enabled) if(execsharp) { if (params->dirpyrequalizer.enabled) { if (params->dirpyrequalizer.gamutlab /*&& execsharp*/) { - float b_l = static_cast (params->dirpyrequalizer.hueskin.value[0]) / 100.0f; - float t_l = static_cast (params->dirpyrequalizer.hueskin.value[1]) / 100.0f; - float b_r = static_cast (params->dirpyrequalizer.hueskin.value[2]) / 100.0f; - float t_r = static_cast (params->dirpyrequalizer.hueskin.value[3]) / 100.0f; - float artifact = (float) settings->artifact_cbdl; if (artifact > 6.f) { @@ -1269,14 +1276,14 @@ void ImProcFunctions::ciecam_02 (CieImage* ncie, double adap, int begh, int endh float chrom = 50.f; { int hotbad = 0; - ImProcFunctions::badpixcam (ncie, artifact, 5, 2, b_l, t_l, t_r, b_r, params->dirpyrequalizer.skinprotect, chrom, hotbad); //enabled remove artifacts for cbDL + ImProcFunctions::badpixcam (ncie, artifact, 5, 2, params->dirpyrequalizer.skinprotect, chrom, hotbad); //enabled remove artifacts for cbDL } } } if (params->colorappearance.badpixsl > 0) if (execsharp) { int mode = params->colorappearance.badpixsl; - ImProcFunctions::badpixcam (ncie, 3.4, 5, mode, 0, 0, 0, 0, 0, 0, 1);//for bad pixels CIECAM + ImProcFunctions::badpixcam (ncie, 3.4, 5, mode, 0, 0, 1);//for bad pixels CIECAM } if (params->sharpenMicro.enabled)if (execsharp) { @@ -1297,10 +1304,8 @@ void ImProcFunctions::ciecam_02 (CieImage* ncie, double adap, int begh, int endh if (rtt == 1) { float b_l = static_cast (params->dirpyrequalizer.hueskin.value[0]) / 100.0f; float t_l = static_cast (params->dirpyrequalizer.hueskin.value[1]) / 100.0f; - float b_r = static_cast (params->dirpyrequalizer.hueskin.value[2]) / 100.0f; float t_r = static_cast (params->dirpyrequalizer.hueskin.value[3]) / 100.0f; - int choice = 0; //not disabled in case of ! always 0 - dirpyr_equalizercam (ncie, ncie->sh_p, ncie->sh_p, ncie->W, ncie->H, ncie->h_p, ncie->C_p, params->dirpyrequalizer.mult, params->dirpyrequalizer.threshold, params->dirpyrequalizer.skinprotect, true, params->dirpyrequalizer.gamutlab, b_l, t_l, t_r, b_r, choice, scale); //contrast by detail adapted to CIECAM + dirpyr_equalizercam (ncie, ncie->sh_p, ncie->sh_p, ncie->W, ncie->H, ncie->h_p, ncie->C_p, params->dirpyrequalizer.mult, params->dirpyrequalizer.threshold, params->dirpyrequalizer.skinprotect, true, b_l, t_l, t_r, scale); //contrast by detail adapted to CIECAM } } @@ -1330,14 +1335,14 @@ void ImProcFunctions::ciecam_02 (CieImage* ncie, double adap, int begh, int endh || (params->colorappearance.badpixsl > 0 && settings->autocielab)) { if (params->epd.enabled && params->colorappearance.tonecie && algepd) { - ImProcFunctions::EPDToneMapCIE (ncie, a_w, c_, w_h, width, height, begh, endh, minQ, maxQ, Iterates, scale ); + ImProcFunctions::EPDToneMapCIE (ncie, a_w, c_, width, height, minQ, maxQ, Iterates, scale ); } //EPDToneMapCIE adapted to CIECAM #ifndef _DEBUG - #pragma omp parallel default(shared) firstprivate(lab,xw2,yw2,zw2,chr,yb,la2,yb2, height,width,begh, endh, nc2,f2,c2, gamu, highlight,pW) + #pragma omp parallel default(shared) firstprivate(lab,xw2,yw2,zw2,chr,yb,la2,yb2, height,width, nc2,f2,c2, gamu, highlight,pW) #endif { TMatrix wiprofa = ICCStore::getInstance()->workingSpaceInverseMatrix (params->icm.working); @@ -1432,8 +1437,7 @@ void ImProcFunctions::ciecam_02 (CieImage* ncie, double adap, int begh, int endh Ciecam02::jch2xyz_ciecam02 ( xx, yy, zz, ncie->J_p[i][j], ncie->C_p[i][j], ncie->h_p[i][j], xw2, yw2, zw2, - yb2, la2, - f2, c2, nc2, gamu, nj, nbbj, ncbj, flj, czj, dj, awj); + c2, nc2, gamu, nj, nbbj, ncbj, flj, czj, dj, awj); x = (float)xx * 655.35; y = (float)yy * 655.35; z = (float)zz * 655.35; @@ -1504,7 +1508,7 @@ void ImProcFunctions::ciecam_02 (CieImage* ncie, double adap, int begh, int endh // Copyright (c) 2012 Jacques Desmis -void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int endh, int pW, int pwb, LabImage* lab, const ProcParams* params, +void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int pW, int pwb, LabImage* lab, const ProcParams* params, const ColorAppearance & customColCurve1, const ColorAppearance & customColCurve2, const ColorAppearance & customColCurve3, LUTu & histLCAM, LUTu & histCCAM, LUTf & CAMBrightCurveJ, LUTf & CAMBrightCurveQ, float &mean, int Iterates, int scale, bool execsharp, float &d, float &dj, float &yb, int rtt) { @@ -1546,9 +1550,9 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int || (params->dirpyrequalizer.enabled && settings->autocielab) || (params->defringe.enabled && settings->autocielab) || (params->sharpenMicro.enabled && settings->autocielab) || (params->impulseDenoise.enabled && settings->autocielab) || (params->colorappearance.badpixsl > 0 && settings->autocielab)); - ColorTemp::temp2mulxyz (params->wb.temperature, params->wb.green, params->wb.method, Xw, Zw); //compute white Xw Yw Zw : white current WB - ColorTemp::temp2mulxyz (params->colorappearance.tempout, params->colorappearance.greenout, "Custom", Xwout, Zwout); - ColorTemp::temp2mulxyz (params->colorappearance.tempsc, params->colorappearance.greensc, "Custom", Xwsc, Zwsc); + ColorTemp::temp2mulxyz (params->wb.temperature, params->wb.method, Xw, Zw); //compute white Xw Yw Zw : white current WB + ColorTemp::temp2mulxyz (params->colorappearance.tempout, "Custom", Xwout, Zwout); + ColorTemp::temp2mulxyz (params->colorappearance.tempsc, "Custom", Xwsc, Zwsc); //viewing condition for surrsrc if (params->colorappearance.surrsrc == "Average") { @@ -1681,10 +1685,11 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int } } - if (alg >= 2 && la < 200.f) { - la = 200.f; - } - + /* + if (alg >= 2 && la < 200.f) { + la = 200.f; + } + */ const float la2 = float (params->colorappearance.adaplum); // level of adaptation @@ -1775,6 +1780,7 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int } float sum = 0.f; +// float sumQ = 0.f; #ifdef _OPENMP const int numThreads = min (max (width * height / 65536, 1), omp_get_max_threads()); @@ -1794,8 +1800,10 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int hist16Qthr.clear(); } + // #pragma omp for reduction(+:sum,sumQ) #pragma omp for reduction(+:sum) + 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; @@ -1839,11 +1847,27 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int hist16Jthr[ (int) ((koef * lab->L[i][j]))]++; //evaluate histogram luminance L # J } + //estimation of wh only with La + /* + float whestim = 500.f; + + if (la < 200.f) { + whestim = 200.f; + } else if (la < 2500.f) { + whestim = 350.f; + } else { + whestim = 500.f; + } + */ if (needQ) { - hist16Qthr[ (int) (sqrtf ((koef * (lab->L[i][j])) * 32768.f))]++; //for brightness Q : approximation for Q=wh*sqrt(J/100) J not equal L + hist16Qthr[CLIP ((int) (32768.f * sqrt ((koef * (lab->L[i][j])) / 32768.f)))]++; //for brightness Q : approximation for Q=wh*sqrt(J/100) J not equal L + //perhaps needs to introduce whestim ?? + //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 + //sumQ += whestim * sqrt ((koef * (lab->L[i][j])) / 32768.f); + //can be used in case of... } #pragma omp critical @@ -1864,7 +1888,6 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int } - //evaluate lightness, contrast } @@ -1937,6 +1960,8 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int float cz, wh, pfl; Ciecam02::initcam1float (gamu, yb, pilot, f, la, xw, yw, zw, n, d, nbb, ncb, cz, aw, wh, pfl, fl, c); + //printf ("wh=%f \n", wh); + const float pow1 = pow_F ( 1.64f - pow_F ( 0.29f, n ), 0.73f ); float nj, nbbj, ncbj, czj, awj, flj; Ciecam02::initcam2float (gamu, yb2, pilotout, f2, la2, xw2, yw2, zw2, nj, dj, nbbj, ncbj, czj, awj, flj); @@ -1944,7 +1969,6 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int const float pow1n = pow_F ( 1.64f - pow_F ( 0.29f, nj ), 0.73f ); const float epsil = 0.0001f; - const float w_h = wh + epsil; const float coefQ = 32767.f / wh; const float a_w = aw; const float c_ = c; @@ -1954,7 +1978,7 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int const bool LabPassOne = ! ((params->colorappearance.tonecie && (epdEnabled)) || (params->sharpening.enabled && settings->autocielab && execsharp) || (params->dirpyrequalizer.enabled && settings->autocielab) || (params->defringe.enabled && settings->autocielab) || (params->sharpenMicro.enabled && settings->autocielab) || (params->impulseDenoise.enabled && settings->autocielab) || (params->colorappearance.badpixsl > 0 && settings->autocielab)); - + //printf("coQ=%f\n", coefQ); if (needJ) { if (!CAMBrightCurveJ) { @@ -1975,7 +1999,7 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int if (CAMBrightCurveQ.dirty) { Ciecam02::curveJfloat (params->colorappearance.qbright, params->colorappearance.qcontrast, hist16Q, CAMBrightCurveQ);//brightness and contrast Q - CAMBrightCurveQ /= coefQ; + // CAMBrightCurveQ /= coefQ; CAMBrightCurveQ.dirty = false; } } @@ -2125,7 +2149,11 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int Qpro = QproFactor * sqrtf (Jpro); Cpro = (spro * spro * Qpro) / (10000.0f); } else if (alg == 2) { - Qpro = CAMBrightCurveQ[ (float) (Qpro * coefQ)]; //brightness and contrast + //printf("Qp0=%f ", Qpro); + + Qpro = CAMBrightCurveQ[ (float) (Qpro * coefQ)] / coefQ; //brightness and contrast + //printf("Qpaf=%f ", Qpro); + float Mp, sres; Mp = Mpro / 100.0f; Ciecam02::curvecolorfloat (mchr, Mp, sres, 2.5f); @@ -2139,7 +2167,7 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int Qpro = (Qpro == 0.f ? epsil : Qpro); // avoid division by zero spro = 100.0f * sqrtf ( Mpro / Qpro ); } else { /*if(alg == 3) */ - Qpro = CAMBrightCurveQ[ (float) (Qpro * coefQ)]; //brightness and contrast + Qpro = CAMBrightCurveQ[ (float) (Qpro * coefQ)] / coefQ; //brightness and contrast float Mp, sres; Mp = Mpro / 100.0f; @@ -2216,6 +2244,7 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int } else if (curveMode == ColorAppearanceParams::TC_MODE_BRIGHT) { //attention! Brightness curves are open - unlike Lightness or Lab or RGB==> rendering and algoritms will be different float coef = ((aw + 4.f) * (4.f / c)) / 100.f; + float Qanc = Qpro; float Qq = (float) Qpro * 327.68f * (1.f / coef); float Qold100 = (float) Qpro / coef; @@ -2241,8 +2270,13 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int Qq = 0.7f * (Qq - Qold) + Qold; // not zero ==>artifacts } - Qpro = (float) (Qq * (coef) / 327.68f); - Jpro = 100.f * (Qpro * Qpro) / ((4.0f / c) * (4.0f / c) * (aw + 4.0f) * (aw + 4.0f)); + if (Qold == 0.f) { + Qold = 0.001f; + } + + Qpro = Qanc * (Qq / Qold); + // Jpro = 100.f * (Qpro * Qpro) / ((4.0f / c) * (4.0f / c) * (aw + 4.0f) * (aw + 4.0f)); + Jpro = Jpro * SQR (Qq / Qold); if (Jpro < 1.f) { Jpro = 1.f; @@ -2290,6 +2324,8 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int } } else if (curveMode2 == ColorAppearanceParams::TC_MODE_BRIGHT) { // + float Qanc = Qpro; + float coef = ((aw + 4.f) * (4.f / c)) / 100.f; float Qq = (float) Qpro * 327.68f * (1.f / coef); float Qold100 = (float) Qpro / coef; @@ -2316,8 +2352,15 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int Qq = 0.7f * (Qq - Qold) + Qold; // not zero ==>artifacts } - Qpro = (float) (Qq * (coef) / 327.68f); - Jpro = 100.f * (Qpro * Qpro) / ((4.0f / c) * (4.0f / c) * (aw + 4.0f) * (aw + 4.0f)); + if (Qold == 0.f) { + Qold = 0.001f; + } + + // Qpro = (float) (Qq * (coef) / 327.68f); + Qpro = Qanc * (Qq / Qold); + Jpro = Jpro * SQR (Qq / Qold); + + // Jpro = 100.f * (Qpro * Qpro) / ((4.0f / c) * (4.0f / c) * (aw + 4.0f) * (aw + 4.0f)); if (t1L) { //to workaround the problem if we modify curve1-lightnees after curve2 brightness(the cat that bites its own tail!) in fact it's another type of curve only for this case coef = 2.f; //adapt Q to J approximation @@ -2548,7 +2591,7 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int Ciecam02::jch2xyz_ciecam02float ( x, y, z, LVF (Jbuffer[k]), LVF (Cbuffer[k]), LVF (hbuffer[k]), F2V (xw2), F2V (yw2), F2V (zw2), - F2V (f2), F2V (nc2), F2V (pow1n), F2V (nbbj), F2V (ncbj), F2V (flj), F2V (dj), F2V (awj), F2V (reccmcz)); + F2V (nc2), F2V (pow1n), F2V (nbbj), F2V (ncbj), F2V (flj), F2V (dj), F2V (awj), F2V (reccmcz)); STVF (xbuffer[k], x * c655d35); STVF (ybuffer[k], y * c655d35); STVF (zbuffer[k], z * c655d35); @@ -2650,10 +2693,6 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int //if(params->dirpyrequalizer.enabled) if(execsharp) { if (params->dirpyrequalizer.enabled) { if (params->dirpyrequalizer.gamutlab /*&& execsharp*/) { //remove artifacts by gaussian blur - skin control - float b_l = static_cast (params->dirpyrequalizer.hueskin.value[0]) / 100.0f; - float t_l = static_cast (params->dirpyrequalizer.hueskin.value[1]) / 100.0f; - float b_r = static_cast (params->dirpyrequalizer.hueskin.value[2]) / 100.0f; - float t_r = static_cast (params->dirpyrequalizer.hueskin.value[3]) / 100.0f; float artifact = (float) settings->artifact_cbdl; if (artifact > 6.f) { @@ -2667,7 +2706,7 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int int hotbad = 0; float chrom = 50.f; lab->deleteLab(); - ImProcFunctions::badpixcam (ncie, artifact, 5, 2, b_l, t_l, t_r, b_r, params->dirpyrequalizer.skinprotect, chrom, hotbad); //enabled remove artifacts for cbDL + ImProcFunctions::badpixcam (ncie, artifact, 5, 2, params->dirpyrequalizer.skinprotect, chrom, hotbad); //enabled remove artifacts for cbDL lab->reallocLab(); } } @@ -2676,7 +2715,7 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int if (params->colorappearance.badpixsl > 0) if (execsharp) { int mode = params->colorappearance.badpixsl; lab->deleteLab(); - ImProcFunctions::badpixcam (ncie, 3.0, 10, mode, 0, 0, 0, 0, 0, 0, 1);//for bad pixels CIECAM + ImProcFunctions::badpixcam (ncie, 3.0, 10, mode, 0, 0, 1);//for bad pixels CIECAM lab->reallocLab(); } @@ -2706,11 +2745,9 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int if (rtt == 1) { float b_l = static_cast (params->dirpyrequalizer.hueskin.value[0]) / 100.0f; float t_l = static_cast (params->dirpyrequalizer.hueskin.value[1]) / 100.0f; - float b_r = static_cast (params->dirpyrequalizer.hueskin.value[2]) / 100.0f; float t_r = static_cast (params->dirpyrequalizer.hueskin.value[3]) / 100.0f; - int choice = 0; // I have not suppress this statement in case of !! always to 0 lab->deleteLab(); - dirpyr_equalizercam (ncie, ncie->sh_p, ncie->sh_p, ncie->W, ncie->H, ncie->h_p, ncie->C_p, params->dirpyrequalizer.mult, params->dirpyrequalizer.threshold, params->dirpyrequalizer.skinprotect, true, params->dirpyrequalizer.gamutlab, b_l, t_l, t_r, b_r, choice, scale); //contrast by detail adapted to CIECAM + dirpyr_equalizercam (ncie, ncie->sh_p, ncie->sh_p, ncie->W, ncie->H, ncie->h_p, ncie->C_p, params->dirpyrequalizer.mult, params->dirpyrequalizer.threshold, params->dirpyrequalizer.skinprotect, true, b_l, t_l, t_r, scale); //contrast by detail adapted to CIECAM lab->reallocLab(); } @@ -2753,7 +2790,7 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int if (epdEnabled && params->colorappearance.tonecie && algepd) { lab->deleteLab(); - ImProcFunctions::EPDToneMapCIE (ncie, a_w, c_, w_h, width, height, begh, endh, minQ, maxQ, Iterates, scale ); + ImProcFunctions::EPDToneMapCIE (ncie, a_w, c_, width, height, minQ, maxQ, Iterates, scale ); lab->reallocLab(); } @@ -2892,7 +2929,7 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int Ciecam02::jch2xyz_ciecam02float ( x, y, z, LVF (Jbuffer[k]), LVF (Cbuffer[k]), LVF (hbuffer[k]), F2V (xw2), F2V (yw2), F2V (zw2), - F2V (f2), F2V (nc2), F2V (pow1n), F2V (nbbj), F2V (ncbj), F2V (flj), F2V (dj), F2V (awj), F2V (reccmcz)); + F2V (nc2), F2V (pow1n), F2V (nbbj), F2V (ncbj), F2V (flj), F2V (dj), F2V (awj), F2V (reccmcz)); x *= c655d35; y *= c655d35; z *= c655d35; @@ -4007,7 +4044,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer float lumbefore = 0.299f * r + 0.587f * g + 0.114f * b; float ro, go, bo; int mode = 0; - toningsmh (r, g, b, ro, go, bo, RedLow, GreenLow, BlueLow, RedMed, GreenMed, BlueMed, RedHigh, GreenHigh, BlueHigh, reducac, mode, preser, strProtect); + toningsmh (r, g, b, ro, go, bo, RedLow, GreenLow, BlueLow, RedMed, GreenMed, BlueMed, RedHigh, GreenHigh, BlueHigh, reducac, mode, strProtect); float lumafter = 0.299f * ro + 0.587f * go + 0.114f * bo; float preserv = 1.f; @@ -4158,21 +4195,21 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer if (beforeCurveMode == BlackWhiteParams::TC_MODE_STD_BW) { // Standard for (int i = istart, ti = 0; i < tH; i++, ti++) { for (int j = jstart, tj = 0; j < tW; j++, tj++) { - const StandardToneCurvebw& userToneCurvebw = static_cast (customToneCurvebw1); + const StandardToneCurve& userToneCurvebw = static_cast (customToneCurvebw1); userToneCurvebw.Apply (rtemp[ti * TS + tj], gtemp[ti * TS + tj], btemp[ti * TS + tj]); } } } else if (beforeCurveMode == BlackWhiteParams::TC_MODE_FILMLIKE_BW) { // Adobe like for (int i = istart, ti = 0; i < tH; i++, ti++) { for (int j = jstart, tj = 0; j < tW; j++, tj++) { - const AdobeToneCurvebw& userToneCurvebw = static_cast (customToneCurvebw1); + const AdobeToneCurve& userToneCurvebw = static_cast (customToneCurvebw1); userToneCurvebw.Apply (rtemp[ti * TS + tj], gtemp[ti * TS + tj], btemp[ti * TS + tj]); } } } else if (beforeCurveMode == BlackWhiteParams::TC_MODE_SATANDVALBLENDING_BW) { // apply the curve on the saturation and value channels for (int i = istart, ti = 0; i < tH; i++, ti++) { for (int j = jstart, tj = 0; j < tW; j++, tj++) { - const SatAndValueBlendingToneCurvebw& userToneCurvebw = static_cast (customToneCurvebw1); + const SatAndValueBlendingToneCurve& userToneCurvebw = static_cast (customToneCurvebw1); rtemp[ti * TS + tj] = CLIP (rtemp[ti * TS + tj]); gtemp[ti * TS + tj] = CLIP (gtemp[ti * TS + tj]); btemp[ti * TS + tj] = CLIP (btemp[ti * TS + tj]); @@ -4182,7 +4219,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer } else if (beforeCurveMode == BlackWhiteParams::TC_MODE_WEIGHTEDSTD_BW) { // apply the curve to the rgb channels, weighted for (int i = istart, ti = 0; i < tH; i++, ti++) { for (int j = jstart, tj = 0; j < tW; j++, tj++) { - const WeightedStdToneCurvebw& userToneCurvebw = static_cast (customToneCurvebw1); + const WeightedStdToneCurve& userToneCurvebw = static_cast (customToneCurvebw1); rtemp[ti * TS + tj] = CLIP (rtemp[ti * TS + tj]); gtemp[ti * TS + tj] = CLIP (gtemp[ti * TS + tj]); btemp[ti * TS + tj] = CLIP (btemp[ti * TS + tj]); @@ -4622,7 +4659,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer for (int i = 0; i < tH; i++) { for (int j = 0; j < tW; j++) { - const StandardToneCurvebw& userToneCurve = static_cast (customToneCurvebw2); + const StandardToneCurve& userToneCurve = static_cast (customToneCurvebw2); userToneCurve.Apply (tmpImage->r (i, j), tmpImage->g (i, j), tmpImage->b (i, j)); } } @@ -4633,7 +4670,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer for (int i = 0; i < tH; i++) { //for ulterior usage if bw data modified for (int j = 0; j < tW; j++) { - const WeightedStdToneCurvebw& userToneCurve = static_cast (customToneCurvebw2); + const WeightedStdToneCurve& userToneCurve = static_cast (customToneCurvebw2); tmpImage->r (i, j) = CLIP (tmpImage->r (i, j)); tmpImage->g (i, j) = CLIP (tmpImage->g (i, j)); @@ -4686,7 +4723,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer if (lumbefore < 65000.f && lumbefore > 500.f) { //reduct artifacts for highlights an extrem shadows float ro, go, bo; int mode = 1; - toningsmh (r, g, b, ro, go, bo, RedLow, GreenLow, BlueLow, RedMed, GreenMed, BlueMed, RedHigh, GreenHigh, BlueHigh, reducac, mode, preser, strProtect); + toningsmh (r, g, b, ro, go, bo, RedLow, GreenLow, BlueLow, RedMed, GreenMed, BlueMed, RedHigh, GreenHigh, BlueHigh, reducac, mode, strProtect); float lumafter = 0.299f * ro + 0.587f * go + 0.114f * bo; float preserv = 1.f; @@ -5028,7 +5065,7 @@ void ImProcFunctions::secondeg_begin (float reducac, float vend, float &aam, flo * @param mode ? * @param preser whether to preserve luminance (if 1) or not **/ -void ImProcFunctions::toningsmh (float r, float g, float b, float &ro, float &go, float &bo, float RedLow, float GreenLow, float BlueLow, float RedMed, float GreenMed, float BlueMed, float RedHigh, float GreenHigh, float BlueHigh, float reducac, int mode, int preser, float strProtect) +void ImProcFunctions::toningsmh (float r, float g, float b, float &ro, float &go, float &bo, float RedLow, float GreenLow, float BlueLow, float RedMed, float GreenMed, float BlueMed, float RedHigh, float GreenHigh, float BlueHigh, float reducac, int mode, float strProtect) { float bmu = mode == 1 ? 0.5f : 0.4f; float RedL = 1.f + (RedLow - 1.f) * 0.4f; @@ -5505,8 +5542,6 @@ void ImProcFunctions::labtoning (float r, float g, float b, float &ro, float &go float opacity2 = (1.f - min (s / satLimit, 1.f) * (1.f - satLimitOpacity)); //float ro, go, bo; - bool chr = true; - bool lum = false; float lm = l; float chromat, luma; @@ -5522,12 +5557,10 @@ void ImProcFunctions::labtoning (float r, float g, float b, float &ro, float &go luma = 1.f - SQR (SQR ((lm * 65535.f) / (cl2Toningcurve[ (lm) * 65535.f]))); //apply C2=f(L) acts only on 'b' } - int todo = 1; - if (algm == 1) { - Color::interpolateRGBColor (realL, iplow, iphigh, algm, opacity, twoc, metchrom, chr, lum, chromat, luma, r, g, b, xl, yl, zl, x2, y2, z2, todo, wp, wip, ro, go, bo); + Color::interpolateRGBColor (realL, iplow, iphigh, algm, opacity, twoc, metchrom, chromat, luma, r, g, b, xl, yl, zl, x2, y2, z2, wp, wip, ro, go, bo); } else { - Color::interpolateRGBColor (realL, iplow, iphigh, algm, opacity2, twoc, metchrom, chr, lum, chromat, luma, r, g, b, xl, yl, zl, x2, y2, z2, todo, wp, wip, ro, go, bo); + Color::interpolateRGBColor (realL, iplow, iphigh, algm, opacity2, twoc, metchrom, chromat, luma, r, g, b, xl, yl, zl, x2, y2, z2, wp, wip, ro, go, bo); } } @@ -5767,7 +5800,7 @@ SSEFUNCTION void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBu // only if user activate Lab adjustments if (autili || butili || ccutili || cclutili || chutili || lhutili || hhutili || clcutili || utili || chromaticity) { - Color::LabGamutMunsell (lold->L[i], lold->a[i], lold->b[i], W, /*corMunsell*/true, /*lumaMuns*/false, params->toneCurve.hrenabled, /*gamut*/true, wip, multiThread); + Color::LabGamutMunsell (lold->L[i], lold->a[i], lold->b[i], W, /*corMunsell*/true, /*lumaMuns*/false, params->toneCurve.hrenabled, /*gamut*/true, wip); } #ifdef __SSE2__ @@ -6321,8 +6354,8 @@ SSEFUNCTION void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBu //#include "cubic.cc" -void ImProcFunctions::colorCurve (LabImage* lold, LabImage* lnew) -{ +//void ImProcFunctions::colorCurve (LabImage* lold, LabImage* lnew) +//{ /* LUT cmultiplier(181021); @@ -6399,7 +6432,7 @@ void ImProcFunctions::colorCurve (LabImage* lold, LabImage* lnew) } */ //delete [] cmultiplier; -} +//} void ImProcFunctions::impulsedenoise (LabImage* lab) { @@ -6438,17 +6471,17 @@ void ImProcFunctions::defringecam (CieImage* ncie) } } -void ImProcFunctions::badpixcam (CieImage* ncie, double rad, int thr, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom, int hotbad) +void ImProcFunctions::badpixcam (CieImage* ncie, double rad, int thr, int mode, float skinprot, float chrom, int hotbad) { if (ncie->W >= 8 && ncie->H >= 8) { - Badpixelscam (ncie, ncie, rad, thr, mode, b_l, t_l, t_r, b_r, skinprot, chrom, hotbad); + Badpixelscam (ncie, ncie, rad, thr, mode, skinprot, chrom, hotbad); } } -void ImProcFunctions::badpixlab (LabImage* lab, double rad, int thr, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom) +void ImProcFunctions::badpixlab (LabImage* lab, double rad, int thr, int mode, float skinprot, float chrom) { if (lab->W >= 8 && lab->H >= 8) { - BadpixelsLab (lab, lab, rad, thr, mode, b_l, t_l, t_r, b_r, skinprot, chrom); + BadpixelsLab (lab, lab, rad, thr, mode, skinprot, chrom); } } @@ -6457,9 +6490,7 @@ void ImProcFunctions::dirpyrequalizer (LabImage* lab, int scale) if (params->dirpyrequalizer.enabled && lab->W >= 8 && lab->H >= 8) { float b_l = static_cast (params->dirpyrequalizer.hueskin.value[0]) / 100.0f; float t_l = static_cast (params->dirpyrequalizer.hueskin.value[1]) / 100.0f; - float b_r = static_cast (params->dirpyrequalizer.hueskin.value[2]) / 100.0f; float t_r = static_cast (params->dirpyrequalizer.hueskin.value[3]) / 100.0f; - int choice = 0; //I have not disabled this statement in case of ! always 0 // if (params->dirpyrequalizer.algo=="FI") choice=0; // else if(params->dirpyrequalizer.algo=="LA") choice=1; float artifact = (float) settings->artifact_cbdl; @@ -6475,14 +6506,14 @@ void ImProcFunctions::dirpyrequalizer (LabImage* lab, int scale) float chrom = 50.f; if (params->dirpyrequalizer.gamutlab) { - ImProcFunctions::badpixlab (lab, artifact, 5, 3, b_l, t_l, t_r, b_r, params->dirpyrequalizer.skinprotect, chrom); //for artifacts + ImProcFunctions::badpixlab (lab, artifact, 5, 3, params->dirpyrequalizer.skinprotect, chrom); //for artifacts } //dirpyrLab_equalizer(lab, lab, params->dirpyrequalizer.mult); - dirpyr_equalizer (lab->L, lab->L, lab->W, lab->H, lab->a, lab->b, lab->a, lab->b, params->dirpyrequalizer.mult, params->dirpyrequalizer.threshold, params->dirpyrequalizer.skinprotect, params->dirpyrequalizer.gamutlab, b_l, t_l, t_r, b_r, choice, scale); + dirpyr_equalizer (lab->L, lab->L, lab->W, lab->H, lab->a, lab->b, params->dirpyrequalizer.mult, params->dirpyrequalizer.threshold, params->dirpyrequalizer.skinprotect, b_l, t_l, t_r, scale); } } -void ImProcFunctions::EPDToneMapCIE (CieImage *ncie, float a_w, float c_, float w_h, int Wid, int Hei, int begh, int endh, float minQ, float maxQ, unsigned int Iterates, int skip) +void ImProcFunctions::EPDToneMapCIE (CieImage *ncie, float a_w, float c_, int Wid, int Hei, float minQ, float maxQ, unsigned int Iterates, int skip) { if (!params->epd.enabled) { @@ -6695,7 +6726,7 @@ void ImProcFunctions::EPDToneMap (LabImage *lab, unsigned int Iterates, int skip } -void ImProcFunctions::getAutoExp (const LUTu &histogram, int histcompr, double defgain, double clip, +void ImProcFunctions::getAutoExp (const LUTu &histogram, int histcompr, double clip, double& expcomp, int& bright, int& contr, int& black, int& hlcompr, int& hlcomprthresh) { @@ -7006,13 +7037,14 @@ double ImProcFunctions::getAutoDistor (const Glib::ustring &fname, int thumb_si int w_raw = -1, h_raw = thumb_size; int w_thumb = -1, h_thumb = thumb_size; - Thumbnail* thumb = rtengine::Thumbnail::loadQuickFromRaw (fname, ri, w_thumb, h_thumb, 1, FALSE); + eSensorType sensorType = rtengine::ST_NONE; + Thumbnail* thumb = rtengine::Thumbnail::loadQuickFromRaw (fname, ri, sensorType, w_thumb, h_thumb, 1, FALSE); if (!thumb) { return 0.0; } - Thumbnail* raw = rtengine::Thumbnail::loadFromRaw (fname, ri, w_raw, h_raw, 1, 1.0, FALSE, 0); + Thumbnail* raw = rtengine::Thumbnail::loadFromRaw (fname, ri, sensorType, w_raw, h_raw, 1, 1.0, FALSE); if (!raw) { delete thumb; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 3ed585894..66b00e8f6 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -54,9 +54,9 @@ class ImProcFunctions void calcVignettingParams (int oW, int oH, const VignettingParams& vignetting, double &w2, double &h2, double& maxRadius, double &v, double &b, double &mul); - void transformPreview (Imagefloat* original, Imagefloat* transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH, const LCPMapper *pLCPMap); void transformLuminanceOnly (Imagefloat* original, Imagefloat* transformed, int cx, int cy, int oW, int oH, int fW, int fH); - void transformHighQuality (Imagefloat* original, Imagefloat* transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH, const LCPMapper *pLCPMap, bool fullImage); + void transformGeneral(bool highQuality, Imagefloat *original, Imagefloat *transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH, const LensCorrection *pLCPMap); + void transformLCPCAOnly(Imagefloat *original, Imagefloat *transformed, int cx, int cy, const LensCorrection *pLCPMap); void sharpenHaloCtrl (float** luminance, float** blurmap, float** base, int W, int H, const SharpeningParams &sharpenParam); void sharpenHaloCtrl (LabImage* lab, float** blurmap, float** base, int W, int H, SharpeningParams &sharpenParam); @@ -70,6 +70,7 @@ class ImProcFunctions bool needsGradient (); bool needsVignetting (); bool needsLCP (); + bool needsLensfun(); // static cmsUInt8Number* Mempro = NULL; inline void interpolateTransformCubic (Imagefloat* src, int xs, int ys, double Dx, double Dy, float *r, float *g, float *b, double mul) @@ -198,7 +199,7 @@ public: ImProcFunctions (const ProcParams* iparams, bool imultiThread = true) : monitorTransform (nullptr), lab2outputTransform (nullptr), output2monitorTransform (nullptr), params (iparams), scale (1), multiThread (imultiThread), lumimul{} {} ~ImProcFunctions (); - + bool needsLuminanceOnly() { return !(needsCA() || needsDistortion() || needsRotation() || needsPerspective() || needsLCP() || needsLensfun()) && (needsVignetting() || needsPCVignetting() || needsGradient());} void setScale (double iscale); bool needsTransform (); @@ -215,7 +216,7 @@ public: double expcomp, int hlcompr, int hlcomprthresh, DCPProfile *dcpProf, const DCPProfile::ApplyState &asIn, LUTu &histToneCurve); void labtoning (float r, float g, float b, float &ro, float &go, float &bo, int algm, int metchrom, int twoc, float satLimit, float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, LUTf & clToningcurve, LUTf & cl2Toningcurve, float iplow, float iphigh, double wp[3][3], double wip[3][3] ); void toning2col (float r, float g, float b, float &ro, float &go, float &bo, float iplow, float iphigh, float rl, float gl, float bl, float rh, float gh, float bh, float SatLow, float SatHigh, float balanS, float balanH, float reducac, int mode, int preser, float strProtect); - void toningsmh (float r, float g, float b, float &ro, float &go, float &bo, float RedLow, float GreenLow, float BlueLow, float RedMed, float GreenMed, float BlueMed, float RedHigh, float GreenHigh, float BlueHigh, float reducac, int mode, int preser, float strProtect); + void toningsmh (float r, float g, float b, float &ro, float &go, float &bo, float RedLow, float GreenLow, float BlueLow, float RedMed, float GreenMed, float BlueMed, float RedHigh, float GreenHigh, float BlueHigh, float reducac, int mode, float strProtect); void toningsmh2 (float r, float g, float b, float &ro, float &go, float &bo, float low[3], float satLow, float med[3], float satMed, float high[3], float satHigh, float reducac, int mode, int preser); void secondeg_begin (float reducac, float vend, float &aam, float &bbm); void secondeg_end (float reducac, float vinf, float &aa, float &bb, float &cc); @@ -224,19 +225,18 @@ public: void moyeqt (Imagefloat* working, float &moyS, float &eqty); void luminanceCurve (LabImage* lold, LabImage* lnew, LUTf &curve); - void ciecam_02float (CieImage* ncie, float adap, int begh, int endh, int pW, int pwb, LabImage* lab, const ProcParams* params, + void ciecam_02float (CieImage* ncie, float adap, int pW, int pwb, LabImage* lab, const ProcParams* params, const ColorAppearance & customColCurve1, const ColorAppearance & customColCurve, const ColorAppearance & customColCurve3, LUTu &histLCAM, LUTu &histCCAM, LUTf & CAMBrightCurveJ, LUTf & CAMBrightCurveQ, float &mean, int Iterates, int scale, bool execsharp, float &d, float &dj, float &yb, int rtt); - void ciecam_02 (CieImage* ncie, double adap, int begh, int endh, int pW, int pwb, LabImage* lab, const ProcParams* params, + void ciecam_02 (CieImage* ncie, double adap, int pW, int pwb, LabImage* lab, const ProcParams* params, const ColorAppearance & customColCurve1, const ColorAppearance & customColCurve, const ColorAppearance & customColCurve3, - LUTu &histLCAM, LUTu &histCCAM, LUTf & CAMBrightCurveJ, LUTf & CAMBrightCurveQ, float &mean, int Iterates, int scale, bool execsharp, double &d, double &dj, double &yb, int rtt); + LUTu &histLCAM, LUTu &histCCAM, LUTf & CAMBrightCurveJ, LUTf & CAMBrightCurveQ, float &mean, int Iterates, int scale, bool execsharp, double &d, double &dj, int rtt); void chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW, LabImage* lold, LabImage* lnew, LUTf &acurve, LUTf &bcurve, LUTf & satcurve, LUTf & satclcurve, LUTf &clcurve, LUTf &curve, bool utili, bool autili, bool butili, bool ccutili, bool cclutili, bool clcutili, LUTu &histCCurve, LUTu &histLurve); void vibrance (LabImage* lab);//Jacques' vibrance - void colorCurve (LabImage* lold, LabImage* lnew); +// void colorCurve (LabImage* lold, LabImage* lnew); void sharpening (LabImage* lab, float** buffer, SharpeningParams &sharpenParam); void sharpeningcam (CieImage* ncie, float** buffer); - void transform (Imagefloat* original, Imagefloat* transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH, - double focalLen, double focalLen35mm, float focusDist, double fNumber, int rawRotationDeg, bool fullImage); + void transform (Imagefloat* original, Imagefloat* transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH, const FramesMetaData *metadata, int rawRotationDeg, bool fullImage); float resizeScale (const ProcParams* params, int fw, int fh, int &imw, int &imh); void lab2monitorRgb (LabImage* lab, Image8* image); void resize (Image16* src, Image16* dst, float dScale); @@ -259,12 +259,12 @@ 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); - float *CompressDR (float *Source, int skip, struct cont_params &cp, int W_L, int H_L, float Compression, float DetailBoost, float max0, float min0, float ave, float ah, float bh, float al, float bl, float factorx, float *Compressed); - void ContrastResid (float * WavCoeffs_L0, unsigned int Iterates, int skip, struct cont_params &cp, int W_L, int H_L, float max0, float min0, float ave, float ah, float bh, float al, float bl, float factorx); - float *ContrastDR (float *Source, int skip, struct cont_params &cp, int W_L, int H_L, float Compression, float DetailBoost, float max0, float min0, float ave, float ah, float bh, float al, float bl, float factorx, float *Contrast = nullptr); + float *CompressDR (float *Source, int W_L, int H_L, float Compression, float DetailBoost, float *Compressed); + void ContrastResid (float * WavCoeffs_L0, struct cont_params &cp, int W_L, int H_L, float max0, float min0); + float *ContrastDR (float *Source, int W_L, int H_L, float *Contrast = nullptr); void EPDToneMap (LabImage *lab, unsigned int Iterates = 0, int skip = 1); - void EPDToneMapCIE (CieImage *ncie, float a_w, float c_, float w_h, int Wid, int Hei, int begh, int endh, float minQ, float maxQ, unsigned int Iterates = 0, int skip = 1); + void EPDToneMapCIE (CieImage *ncie, float a_w, float c_, int Wid, int Hei, float minQ, float maxQ, unsigned int Iterates = 0, int skip = 1); // pyramid denoise procparams::DirPyrDenoiseParams dnparams; @@ -274,25 +274,25 @@ public: int pitch, int scale, const int luma, const int chroma/*, LUTf & Lcurve, LUTf & abcurve*/ ); 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, bool wavcontlutili, int skip); + 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 WaveletcontAllL (LabImage * lab, float **varhue, float **varchrom, wavelet_decomposition &WaveletCoeffs_L, - struct cont_params &cp, int skip, float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveWL & waOpacityCurveWL, FlatCurve* ChCurve, bool Chutili); + 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 (LabImage * lab, float **varhue, float **varchrom, wavelet_decomposition &WaveletCoeffs_a, wavelet_decomposition &WaveletCoeffs_b, - struct cont_params &cp, const WavOpacityCurveW & waOpacityCurveW, FlatCurve* hhcurve, bool hhutili); + void WaveletAandBAllAB (wavelet_decomposition &WaveletCoeffs_a, wavelet_decomposition &WaveletCoeffs_b, + struct 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 *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, FlatCurve* ChCurve, bool Chutili); + 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, 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, - const struct cont_params& cp, int ind, float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN, float madL[8][3]); - void Eval2 (float ** WavCoeffs_L, int level, const struct cont_params& cp, - int W_L, int H_L, int skip_L, int ind, float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN, float *madL); + 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 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); @@ -301,7 +301,8 @@ public: void Median_Denoise ( float **src, float **dst, int width, int height, Median medianType, int iterations, int numThreads, float **buffer = nullptr); - void RGB_denoise (int kall, Imagefloat * src, Imagefloat * dst, Imagefloat * calclum, float * ch_M, float *max_r, float *max_b, bool isRAW, const procparams::DirPyrDenoiseParams & dnparams, const double expcomp, const NoiseCurve & noiseLCurve, const NoiseCurve & noiseCCurve, float &chaut, float &redaut, float &blueaut, float &maxredaut, float & maxblueaut, float &nresi, float &highresi); + void Median_Denoise ( float **src, float **dst, float upperBound, int width, int height, Median medianType, int iterations, int numThreads, float **buffer = nullptr); + void RGB_denoise (int kall, Imagefloat * src, Imagefloat * dst, Imagefloat * calclum, float * ch_M, float *max_r, float *max_b, bool isRAW, const procparams::DirPyrDenoiseParams & dnparams, const double expcomp, const NoiseCurve & noiseLCurve, const NoiseCurve & noiseCCurve, float &nresi, float &highresi); void RGB_denoise_infoGamCurve (const procparams::DirPyrDenoiseParams & dnparams, const bool isRAW, LUTf &gamcurve, float &gam, float &gamthresh, float &gamslope); void RGB_denoise_info (Imagefloat * src, Imagefloat * provicalc, bool isRAW, 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, float * nbrwt, float * blurbuffer ); //for DCT @@ -309,8 +310,8 @@ public: bool WaveletDenoiseAllL (wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3], float * vari, int edge); bool WaveletDenoiseAllAB (wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb); void WaveletDenoiseAll_info (int levwav, wavelet_decomposition &WaveletCoeffs_a, - wavelet_decomposition &WaveletCoeffs_b, float **noisevarlum, float **noisevarchrom, float **noisevarhue, int width, int height, float noisevar_abr, float noisevar_abb, LabImage * noi, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float &maxblueaut, float &minredaut, float & minblueaut, int schoice, bool autoch, 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 multiThread); + 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 WaveletDenoiseAll_BiShrinkL (wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3]); bool WaveletDenoiseAll_BiShrinkAB (wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float noisevar_ab, @@ -318,9 +319,9 @@ public: void ShrinkAllL (wavelet_decomposition &WaveletCoeffs_L, float **buffer, int level, int dir, float *noisevarlum, float * madL, float * vari, int edge); void ShrinkAllAB (wavelet_decomposition &WaveletCoeffs_L, 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 * madaab = nullptr, bool madCalculated = false); - void ShrinkAll_info (float ** WavCoeffs_a, float ** WavCoeffs_b, int level, - int W_ab, int H_ab, int skip_ab, float **noisevarlum, float **noisevarchrom, float **noisevarhue, int width, int height, float noisevar_abr, float noisevar_abb, LabImage * noi, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float &maxblueaut, float &minredaut, float &minblueaut, bool autoch, 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, bool multiThread); + 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); void Noise_residualAB (wavelet_decomposition &WaveletCoeffs_ab, float &chresid, float &chmaxresid, bool denoiseMethodRgb); void calcautodn_info (float &chaut, float &delta, int Nb, int levaut, float maxmax, float lumema, float chromina, int mode, int lissage, float redyel, float skinc, float nsknc); float MadMax (float * DataList, int &max, int datalen); @@ -331,30 +332,32 @@ public: void removeSpots (Imagefloat* img, const std::vector &entries, const PreviewProps &pp); // pyramid wavelet - void dirpyr_equalizer (float ** src, float ** dst, int srcwidth, int srcheight, float ** l_a, float ** l_b, float ** dest_a, float ** dest_b, const double * mult, const double dirpyrThreshold, const double skinprot, const bool gamutlab, float b_l, float t_l, float t_r, float b_r, int choice, int scale);//Emil's directional pyramid wavelet - void dirpyr_equalizercam (CieImage* ncie, float ** src, float ** dst, int srcwidth, int srcheight, float ** h_p, float ** C_p, const double * mult, const double dirpyrThreshold, const double skinprot, bool execdir, const bool gamutlab, float b_l, float t_l, float t_r, float b_r, int choice, int scale);//Emil's directional pyramid wavelet + void dirpyr_equalizer (float ** src, float ** dst, int srcwidth, int srcheight, float ** l_a, float ** l_b, const double * mult, const double dirpyrThreshold, const double skinprot, float b_l, float t_l, float t_r, int scale);//Emil's directional pyramid wavelet + void dirpyr_equalizercam (CieImage* ncie, float ** src, float ** dst, int srcwidth, int srcheight, float ** h_p, float ** C_p, const double * mult, const double dirpyrThreshold, const double skinprot, bool execdir, float b_l, float t_l, float t_r, int scale);//Emil's directional pyramid wavelet void dirpyr_channel (float ** data_fine, float ** data_coarse, int width, int height, int level, int scale); - void idirpyr_eq_channel (float ** data_coarse, float ** data_fine, float ** buffer, int width, int height, int level, float multi[6], const double dirpyrThreshold, float ** l_a_h, float ** l_b_c, const double skinprot, const bool gamutlab, float b_l, float t_l, float t_r, float b_r, int choice); + void idirpyr_eq_channel (float ** data_coarse, float ** data_fine, float ** buffer, int width, int height, int level, float multi[6], const double dirpyrThreshold, float ** l_a_h, float ** l_b_c, const double skinprot, float b_l, float t_l, float t_r); void idirpyr_eq_channelcam (float ** data_coarse, float ** data_fine, float ** buffer, int width, int height, int level, float multi[6], const double dirpyrThreshold, float ** l_a_h, float ** l_b_c, const double skinprot, float b_l, float t_l, float t_r); void defringe (LabImage* lab); void defringecam (CieImage* ncie); - void badpixcam (CieImage* ncie, double rad, int thr, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom, int hotbad); - void badpixlab (LabImage* lab, double rad, int thr, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom); + void badpixcam (CieImage* ncie, double rad, int thr, int mode, float skinprot, float chrom, int hotbad); + void badpixlab (LabImage* lab, double rad, int thr, int mode, float skinprot, float chrom); void PF_correct_RT (LabImage * src, LabImage * dst, double radius, int thresh); void PF_correct_RTcam (CieImage * src, CieImage * dst, double radius, int thresh); - void Badpixelscam (CieImage * src, CieImage * dst, double radius, int thresh, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom, int hotbad); - void BadpixelsLab (LabImage * src, LabImage * dst, double radius, int thresh, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom); + void Badpixelscam (CieImage * src, CieImage * dst, double radius, int thresh, int mode, float skinprot, float chrom, int hotbad); + void BadpixelsLab (LabImage * src, LabImage * dst, double radius, int thresh, int mode, float skinprot, float chrom); + void ToneMapFattal02(Imagefloat *rgb); + Image8* lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, const procparams::ColorManagementParams &icm); - Image16* lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, const procparams::ColorManagementParams &icm, bool bw, GammaValues *ga = nullptr); + Image16* lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, const procparams::ColorManagementParams &icm, GammaValues *ga = nullptr); // CieImage *ciec; - bool transCoord (int W, int H, int x, int y, int w, int h, int& xv, int& yv, int& wv, int& hv, double ascaleDef = -1, const LCPMapper *pLCPMap = nullptr); - bool transCoord (int W, int H, const std::vector &src, std::vector &red, std::vector &green, std::vector &blue, double ascaleDef = -1, const LCPMapper *pLCPMap = nullptr); - static void getAutoExp (const LUTu & histogram, int histcompr, double defgain, double clip, double& expcomp, int& bright, int& contr, int& black, int& hlcompr, int& hlcomprthresh); + bool transCoord (int W, int H, int x, int y, int w, int h, int& xv, int& yv, int& wv, int& hv, double ascaleDef = -1, const LensCorrection *pLCPMap = nullptr); + bool transCoord (int W, int H, const std::vector &src, std::vector &red, std::vector &green, std::vector &blue, double ascaleDef = -1, const LensCorrection *pLCPMap = nullptr); + static void getAutoExp (const LUTu & histogram, int histcompr, double clip, double& expcomp, int& bright, int& contr, int& black, int& hlcompr, int& hlcomprthresh); static double getAutoDistor (const Glib::ustring& fname, int thumb_size); - double getTransformAutoFill (int oW, int oH, const LCPMapper *pLCPMap = nullptr); + double getTransformAutoFill (int oW, int oH, const LensCorrection *pLCPMap = nullptr); void rgb2lab (const Imagefloat &src, LabImage &dst, const Glib::ustring &workingSpace); void lab2rgb (const LabImage &src, Imagefloat &dst, const Glib::ustring &workingSpace); }; diff --git a/rtengine/impulse_denoise.h b/rtengine/impulse_denoise.cc similarity index 100% rename from rtengine/impulse_denoise.h rename to rtengine/impulse_denoise.cc diff --git a/rtengine/init.cc b/rtengine/init.cc index 2d157c762..8d2cf9174 100644 --- a/rtengine/init.cc +++ b/rtengine/init.cc @@ -30,6 +30,7 @@ #include "rtthumbnail.h" #include "profilestore.h" #include "../rtgui/threadutils.h" +#include "rtlensfun.h" namespace rtengine { @@ -37,23 +38,71 @@ namespace rtengine const Settings* settings; MyMutex* lcmsMutex = nullptr; +MyMutex *fftwMutex = nullptr; int init (const Settings* s, Glib::ustring baseDir, Glib::ustring userSettingsDir, bool loadAll) { settings = s; - ProfileStore::getInstance()->init (loadAll); - ICCStore::getInstance()->init (s->iccDirectory, Glib::build_filename (baseDir, "iccprofiles"), loadAll); - DCPStore::getInstance()->init (Glib::build_filename (baseDir, "dcpprofiles"), loadAll); + ProcParams::init(); + PerceptualToneCurve::init(); + RawImageSource::init(); + +#ifdef _OPENMP +#pragma omp parallel sections +#endif +{ +#ifdef _OPENMP +#pragma omp section +#endif +{ + if (s->lensfunDbDirectory.empty() || Glib::path_is_absolute(s->lensfunDbDirectory)) { + LFDatabase::init(s->lensfunDbDirectory); + } else { + LFDatabase::init(Glib::build_filename(baseDir, s->lensfunDbDirectory)); + } +} +#ifdef _OPENMP +#pragma omp section +#endif +{ + ProfileStore::getInstance()->init(loadAll); +} +#ifdef _OPENMP +#pragma omp section +#endif +{ + ICCStore::getInstance()->init(s->iccDirectory, Glib::build_filename (baseDir, "iccprofiles"), loadAll); +} +#ifdef _OPENMP +#pragma omp section +#endif +{ + DCPStore::getInstance()->init(Glib::build_filename (baseDir, "dcpprofiles"), loadAll); +} +#ifdef _OPENMP +#pragma omp section +#endif +{ + CameraConstantsStore::getInstance()->init(baseDir, userSettingsDir); +} +#ifdef _OPENMP +#pragma omp section +#endif +{ + dfm.init(s->darkFramesPath); +} +#ifdef _OPENMP +#pragma omp section +#endif +{ + ffm.init(s->flatFieldsPath); +} +} - CameraConstantsStore::getInstance ()->init (baseDir, userSettingsDir); - ProcParams::init (); Color::init (); - PerceptualToneCurve::init (); - RawImageSource::init (); delete lcmsMutex; lcmsMutex = new MyMutex; - dfm.init( s->darkFramesPath ); - ffm.init( s->flatFieldsPath ); + fftwMutex = new MyMutex; return 0; } diff --git a/rtengine/iplab2rgb.cc b/rtengine/iplab2rgb.cc index dac24411d..abef0a878 100644 --- a/rtengine/iplab2rgb.cc +++ b/rtengine/iplab2rgb.cc @@ -262,7 +262,7 @@ Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, * If a custom gamma profile can be created, divide by 327.68, convert to xyz and apply the custom gamma transform * otherwise divide by 327.68, convert to xyz and apply the sRGB transform, before converting with gamma2curve */ -Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, const procparams::ColorManagementParams &icm, bool bw, GammaValues *ga) +Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, const procparams::ColorManagementParams &icm, GammaValues *ga) { if (cx < 0) { diff --git a/rtengine/iptransform.cc b/rtengine/iptransform.cc index ee14c80c2..ff976137e 100644 --- a/rtengine/iptransform.cc +++ b/rtengine/iptransform.cc @@ -24,6 +24,7 @@ #include "mytime.h" #include "rt_math.h" #include "sleef.c" +#include "rtlensfun.h" using namespace std; @@ -86,18 +87,6 @@ float normn (float a, float b, int n) } -void correct_distortion(const rtengine::LCPMapper *lcp, double &x, double &y, - int cx, int cy, double scale) -{ - assert (lcp); - - x += cx; - y += cy; - lcp->correctDistortion(x, y, scale); - x -= (cx * scale); - y -= (cy * scale); -} - } namespace rtengine @@ -107,7 +96,7 @@ namespace rtengine #define CLIPTOC(a,b,c,d) ((a)>=(b)?((a)<=(c)?(a):(d=true,(c))):(d=true,(b))) bool ImProcFunctions::transCoord (int W, int H, const std::vector &src, std::vector &red, std::vector &green, std::vector &blue, double ascaleDef, - const LCPMapper *pLCPMap) + const LensCorrection *pLCPMap) { bool clipped = false; @@ -157,7 +146,7 @@ bool ImProcFunctions::transCoord (int W, int H, const std::vector &src, double x_d = src[i].x, y_d = src[i].y; if (pLCPMap && params->lensProf.useDist) { - correct_distortion (pLCPMap, x_d, y_d, 0, 0, ascale); + pLCPMap->correctDistortion(x_d, y_d, 0, 0, ascale); } else { x_d *= ascale; y_d *= ascale; @@ -209,7 +198,7 @@ bool ImProcFunctions::transCoord (int W, int H, const std::vector &src, } // Transform all corners and critical sidelines of an image -bool ImProcFunctions::transCoord (int W, int H, int x, int y, int w, int h, int& xv, int& yv, int& wv, int& hv, double ascaleDef, const LCPMapper *pLCPMap) +bool ImProcFunctions::transCoord (int W, int H, int x, int y, int w, int h, int& xv, int& yv, int& wv, int& hv, double ascaleDef, const LensCorrection *pLCPMap) { const int DivisionsPerBorder = 32; @@ -307,35 +296,60 @@ bool ImProcFunctions::transCoord (int W, int H, int x, int y, int w, int h, int& } void ImProcFunctions::transform (Imagefloat* original, Imagefloat* transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH, - double focalLen, double focalLen35mm, float focusDist, double fNumber, int rawRotationDeg, bool fullImage) + const FramesMetaData *metadata, + int rawRotationDeg, bool fullImage) { + double focalLen = metadata->getFocalLen(); + double focalLen35mm = metadata->getFocalLen35mm(); + float focusDist = metadata->getFocusDist(); + double fNumber = metadata->getFNumber(); - LCPMapper *pLCPMap = nullptr; + std::unique_ptr pLCPMap; - if (needsLCP()) { // don't check focal length to allow distortion correction for lenses without chip - LCPProfile *pLCPProf = lcpStore->getProfile (params->lensProf.lcpFile); + if (needsLensfun()) { + pLCPMap = LFDatabase::findModifier(params->lensProf, metadata, oW, oH, params->coarse, rawRotationDeg); + } else if (needsLCP()) { // don't check focal length to allow distortion correction for lenses without chip + const std::shared_ptr pLCPProf = LCPStore::getInstance()->getProfile (params->lensProf.lcpFile); if (pLCPProf) { - pLCPMap = new LCPMapper (pLCPProf, focalLen, focalLen35mm, - focusDist, fNumber, false, - params->lensProf.useDist, - oW, oH, params->coarse, rawRotationDeg); + pLCPMap.reset( + new LCPMapper (pLCPProf, focalLen, focalLen35mm, + focusDist, fNumber, false, + false, + oW, oH, params->coarse, rawRotationDeg + ) + ); } } - if (! (needsCA() || needsDistortion() || needsRotation() || needsPerspective() || needsLCP()) && (needsVignetting() || needsPCVignetting() || needsGradient())) { + if (! (needsCA() || needsDistortion() || needsRotation() || needsPerspective() || needsLCP() || needsLensfun()) && (needsVignetting() || needsPCVignetting() || needsGradient())) { transformLuminanceOnly (original, transformed, cx, cy, oW, oH, fW, fH); - } else if (!needsCA() && scale != 1) { - transformPreview (original, transformed, cx, cy, sx, sy, oW, oH, fW, fH, pLCPMap); } else { - transformHighQuality (original, transformed, cx, cy, sx, sy, oW, oH, fW, fH, pLCPMap, fullImage); - } - - if (pLCPMap) { - delete pLCPMap; + bool highQuality; + std::unique_ptr tmpimg; + if (!needsCA() && scale != 1) { + highQuality = false; + } else { + highQuality = true; + // agriggio: CA correction via the lens profile has to be + // performed before all the other transformations (except for the + // coarse rotation/flipping). In order to not change the code too + // much, I simply introduced a new mode + // TRANSFORM_HIGH_QUALITY_CA, which applies *only* + // profile-based CA correction. So, the correction in this case + // occurs in two steps, using an intermediate temporary + // image. There's room for optimization of course... + if (pLCPMap && params->lensProf.useCA && pLCPMap->isCACorrectionAvailable()) { + tmpimg.reset(new Imagefloat(original->getWidth(), original->getHeight())); + transformLCPCAOnly(original, tmpimg.get(), cx, cy, pLCPMap.get()); + original = tmpimg.get(); + } + } + transformGeneral(highQuality, original, transformed, cx, cy, sx, sy, oW, oH, fW, fH, pLCPMap.get()); } } + // helper function void ImProcFunctions::calcVignettingParams (int oW, int oH, const VignettingParams& vignetting, double &w2, double &h2, double& maxRadius, double &v, double &b, double &mul) { @@ -721,10 +735,18 @@ void ImProcFunctions::transformLuminanceOnly (Imagefloat* original, Imagefloat* } } -// Transform WITH scaling (opt.) and CA, cubic interpolation -void ImProcFunctions::transformHighQuality (Imagefloat* original, Imagefloat* transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH, - const LCPMapper *pLCPMap, bool fullImage) + +void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, Imagefloat *transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH, const LensCorrection *pLCPMap) { + // set up stuff, depending on the mode we are + bool enableLCPDist = pLCPMap && params->lensProf.useDist; + bool enableCA = highQuality && needsCA(); + bool enableGradient = needsGradient(); + bool enablePCVignetting = needsPCVignetting(); + bool enableVignetting = needsVignetting(); + bool enablePerspective = needsPerspective(); + bool enableDistortion = needsDistortion(); + double w2 = (double) oW / 2.0 - 0.5; double h2 = (double) oH / 2.0 - 0.5; @@ -733,13 +755,13 @@ void ImProcFunctions::transformHighQuality (Imagefloat* original, Imagefloat* tr struct grad_params gp; - if (needsGradient()) { + if (enableGradient) { calcGradientParams (oW, oH, params->gradient, gp); } struct pcv_params pcv; - if (needsPCVignetting()) { + if (enablePCVignetting) { calcPCVignetteParams (fW, fH, oW, oH, params->pcvignette, params->crop, pcv); } @@ -755,12 +777,11 @@ void ImProcFunctions::transformHighQuality (Imagefloat* original, Imagefloat* tr // auxiliary variables for c/a correction double chDist[3]; - chDist[0] = params->cacorrection.red; + chDist[0] = enableCA ? params->cacorrection.red : 0.0; chDist[1] = 0.0; - chDist[2] = params->cacorrection.blue; + chDist[2] = enableCA ? params->cacorrection.blue : 0.0; // auxiliary variables for distortion correction - bool needsDist = needsDistortion(); // for performance double distAmount = params->distortion.amount; // auxiliary variables for rotation @@ -781,18 +802,15 @@ void ImProcFunctions::transformHighQuality (Imagefloat* original, Imagefloat* tr oH * tan (hpalpha) * sqrt (SQR (4 * maxRadius) + SQR (oH * tan (hpalpha)))) / (SQR (maxRadius) * 8))); double hpcospt = (hpdeg >= 0 ? 1.0 : -1.0) * cos (hpteta), hptanpt = tan (hpteta); - double ascale = params->commonTrans.autofill ? getTransformAutoFill (oW, oH, true /*fullImage*/ ? pLCPMap : nullptr) : 1.0; - - // smaller crop images are a problem, so only when processing fully - bool enableLCPCA = pLCPMap && params->lensProf.useCA && fullImage && pLCPMap->enableCA; - bool enableLCPDist = pLCPMap && params->lensProf.useDist; // && fullImage; - - if (enableLCPCA) { - enableLCPDist = false; - } - - bool enableCA = enableLCPCA || needsCA(); + double ascale = params->commonTrans.autofill ? getTransformAutoFill (oW, oH, pLCPMap) : 1.0; +#if defined( __GNUC__ ) && __GNUC__ >= 7// silence warning +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" +#endif +#if defined( __GNUC__ ) && __GNUC__ >= 7 +#pragma GCC diagnostic pop +#endif // main cycle bool darkening = (params->vignetting.amount <= 0.0); #pragma omp parallel for if (multiThread) @@ -802,7 +820,7 @@ void ImProcFunctions::transformHighQuality (Imagefloat* original, Imagefloat* tr double x_d = x, y_d = y; if (enableLCPDist) { - correct_distortion(pLCPMap, x_d, y_d, cx, cy, ascale); // must be first transform + pLCPMap->correctDistortion(x_d, y_d, cx, cy, ascale); // must be first transform } else { x_d *= ascale; y_d *= ascale; @@ -813,12 +831,12 @@ void ImProcFunctions::transformHighQuality (Imagefloat* original, Imagefloat* tr double vig_x_d = 0., vig_y_d = 0.; - if (needsVignetting()) { + if (enableVignetting) { vig_x_d = ascale * (x + cx - vig_w2); // centering x coord & scale vig_y_d = ascale * (y + cy - vig_h2); // centering y coord & scale } - if (needsPerspective()) { + if (enablePerspective) { // horizontal perspective transformation y_d *= maxRadius / (maxRadius + x_d * hptanpt); x_d *= maxRadius * hpcospt / (maxRadius + x_d * hptanpt); @@ -835,14 +853,14 @@ void ImProcFunctions::transformHighQuality (Imagefloat* original, Imagefloat* tr // distortion correction double s = 1; - if (needsDist) { + if (enableDistortion) { double r = sqrt (Dxc * Dxc + Dyc * Dyc) / maxRadius; // sqrt is slow s = 1.0 - distAmount + distAmount * r ; } double r2 = 0.; - if (needsVignetting()) { + if (enableVignetting) { double vig_Dx = vig_x_d * cost - vig_y_d * sint; double vig_Dy = vig_x_d * sint + vig_y_d * cost; r2 = sqrt (vig_Dx * vig_Dx + vig_Dy * vig_Dy); @@ -856,11 +874,6 @@ void ImProcFunctions::transformHighQuality (Imagefloat* original, Imagefloat* tr Dx += w2; Dy += h2; - // LCP CA - if (enableLCPCA) { - pLCPMap->correctCA (Dx, Dy, c); - } - // Extract integer and fractions of source screen coordinates int xc = (int)Dx; Dx -= (double)xc; @@ -875,7 +888,7 @@ void ImProcFunctions::transformHighQuality (Imagefloat* original, Imagefloat* tr // multiplier for vignetting correction double vignmul = 1.0; - if (needsVignetting()) { + if (enableVignetting) { if (darkening) { vignmul /= std::max (v + mul * tanh (b * (maxRadius - s * r2) / maxRadius), 0.001); } else { @@ -883,11 +896,11 @@ void ImProcFunctions::transformHighQuality (Imagefloat* original, Imagefloat* tr } } - if (needsGradient()) { + if (enableGradient) { vignmul *= calcGradientFactor (gp, cx + x, cy + y); } - if (needsPCVignetting()) { + if (enablePCVignetting) { vignmul *= calcPCVignetteFactor (pcv, cx + x, cy + y); } @@ -895,6 +908,10 @@ void ImProcFunctions::transformHighQuality (Imagefloat* original, Imagefloat* tr // all interpolation pixels inside image if (enableCA) { interpolateTransformChannelsCubic (chOrig[c], xc - 1, yc - 1, Dx, Dy, & (chTrans[c][y][x]), vignmul); + } else if (!highQuality) { + transformed->r (y, x) = vignmul * (original->r (yc, xc) * (1.0 - Dx) * (1.0 - Dy) + original->r (yc, xc + 1) * Dx * (1.0 - Dy) + original->r (yc + 1, xc) * (1.0 - Dx) * Dy + original->r (yc + 1, xc + 1) * Dx * Dy); + transformed->g (y, x) = vignmul * (original->g (yc, xc) * (1.0 - Dx) * (1.0 - Dy) + original->g (yc, xc + 1) * Dx * (1.0 - Dy) + original->g (yc + 1, xc) * (1.0 - Dx) * Dy + original->g (yc + 1, xc + 1) * Dx * Dy); + transformed->b (y, x) = vignmul * (original->b (yc, xc) * (1.0 - Dx) * (1.0 - Dy) + original->b (yc, xc + 1) * Dx * (1.0 - Dy) + original->b (yc + 1, xc) * (1.0 - Dx) * Dy + original->b (yc + 1, xc + 1) * Dx * Dy); } else { interpolateTransformCubic (original, xc - 1, yc - 1, Dx, Dy, & (transformed->r (y, x)), & (transformed->g (y, x)), & (transformed->b (y, x)), vignmul); } @@ -928,168 +945,64 @@ void ImProcFunctions::transformHighQuality (Imagefloat* original, Imagefloat* tr } } -// Transform WITH scaling, WITHOUT CA, simple (and fast) interpolation. Used for preview -void ImProcFunctions::transformPreview (Imagefloat* original, Imagefloat* transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH, const LCPMapper *pLCPMap) + +void ImProcFunctions::transformLCPCAOnly(Imagefloat *original, Imagefloat *transformed, int cx, int cy, const LensCorrection *pLCPMap) { + assert(pLCPMap && params->lensProf.useCA && pLCPMap->isCACorrectionAvailable()); - double w2 = (double) oW / 2.0 - 0.5; - double h2 = (double) oH / 2.0 - 0.5; + float** chOrig[3]; + chOrig[0] = original->r.ptrs; + chOrig[1] = original->g.ptrs; + chOrig[2] = original->b.ptrs; - double vig_w2, vig_h2, maxRadius, v, b, mul; - calcVignettingParams (oW, oH, params->vignetting, vig_w2, vig_h2, maxRadius, v, b, mul); + float** chTrans[3]; + chTrans[0] = transformed->r.ptrs; + chTrans[1] = transformed->g.ptrs; + chTrans[2] = transformed->b.ptrs; - struct grad_params gp; - - if (needsGradient()) { - calcGradientParams (oW, oH, params->gradient, gp); - } - - struct pcv_params pcv; - - if (needsPCVignetting()) { - calcPCVignetteParams (fW, fH, oW, oH, params->pcvignette, params->crop, pcv); - } - - // auxiliary variables for distortion correction - bool needsDist = needsDistortion(); // for performance - double distAmount = params->distortion.amount; - - // auxiliary variables for rotation - double cost = cos (params->rotate.degree * rtengine::RT_PI / 180.0); - double sint = sin (params->rotate.degree * rtengine::RT_PI / 180.0); - - // auxiliary variables for vertical perspective correction - double vpdeg = params->perspective.vertical / 100.0 * 45.0; - double vpalpha = (90 - vpdeg) / 180.0 * rtengine::RT_PI; - double vpteta = fabs (vpalpha - rtengine::RT_PI / 2) < 3e-4 ? 0.0 : acos ((vpdeg > 0 ? 1.0 : -1.0) * sqrt ((-oW * oW * tan (vpalpha) * tan (vpalpha) + (vpdeg > 0 ? 1.0 : -1.0) * oW * tan (vpalpha) * sqrt (16 * maxRadius * maxRadius + oW * oW * tan (vpalpha) * tan (vpalpha))) / (maxRadius * maxRadius * 8))); - double vpcospt = (vpdeg >= 0 ? 1.0 : -1.0) * cos (vpteta), vptanpt = tan (vpteta); - - // auxiliary variables for horizontal perspective correction - double hpdeg = params->perspective.horizontal / 100.0 * 45.0; - double hpalpha = (90 - hpdeg) / 180.0 * rtengine::RT_PI; - double hpteta = fabs (hpalpha - rtengine::RT_PI / 2) < 3e-4 ? 0.0 : acos ((hpdeg > 0 ? 1.0 : -1.0) * sqrt ((-oH * oH * tan (hpalpha) * tan (hpalpha) + (hpdeg > 0 ? 1.0 : -1.0) * oH * tan (hpalpha) * sqrt (16 * maxRadius * maxRadius + oH * oH * tan (hpalpha) * tan (hpalpha))) / (maxRadius * maxRadius * 8))); - double hpcospt = (hpdeg >= 0 ? 1.0 : -1.0) * cos (hpteta), hptanpt = tan (hpteta); - - double ascale = params->commonTrans.autofill ? getTransformAutoFill (oW, oH, pLCPMap) : 1.0; - - bool darkening = (params->vignetting.amount <= 0.0); - - // main cycle #pragma omp parallel for if (multiThread) for (int y = 0; y < transformed->getHeight(); y++) { for (int x = 0; x < transformed->getWidth(); x++) { - double x_d = x, y_d = y; + for (int c = 0; c < 3; c++) { + double Dx = x; + double Dy = y; + + pLCPMap->correctCA(Dx, Dy, cx, cy, c); - if (pLCPMap && params->lensProf.useDist) { - correct_distortion(pLCPMap, x_d, y_d, cx, cy, ascale); // must be first transform - } else { - x_d *= ascale; - y_d *= ascale; - } + // Extract integer and fractions of coordinates + int xc = (int)Dx; + Dx -= (double)xc; + int yc = (int)Dy; + Dy -= (double)yc; - x_d += ascale * (cx - w2); // centering x coord & scale - y_d += ascale * (cy - h2); // centering y coord & scale + // Convert only valid pixels + if (yc >= 0 && yc < original->getHeight() && xc >= 0 && xc < original->getWidth()) { - double vig_x_d = 0., vig_y_d = 0.; - - if (needsVignetting()) { - vig_x_d = ascale * (x + cx - vig_w2); // centering x coord & scale - vig_y_d = ascale * (y + cy - vig_h2); // centering y coord & scale - } - - if (needsPerspective()) { - // horizontal perspective transformation - y_d *= maxRadius / (maxRadius + x_d * hptanpt); - x_d *= maxRadius * hpcospt / (maxRadius + x_d * hptanpt); - - // vertical perspective transformation - x_d *= maxRadius / (maxRadius - y_d * vptanpt); - y_d *= maxRadius * vpcospt / (maxRadius - y_d * vptanpt); - } - - // rotate - double Dx = x_d * cost - y_d * sint; - double Dy = x_d * sint + y_d * cost; - - // distortion correction - double s = 1; - - if (needsDist) { - double r = sqrt (Dx * Dx + Dy * Dy) / maxRadius; // sqrt is slow - s = 1.0 - distAmount + distAmount * r ; - Dx *= s; - Dy *= s; - } - - double r2 = 0.; - - if (needsVignetting()) { - double vig_Dx = vig_x_d * cost - vig_y_d * sint; - double vig_Dy = vig_x_d * sint + vig_y_d * cost; - r2 = sqrt (vig_Dx * vig_Dx + vig_Dy * vig_Dy); - } - - // de-center - Dx += w2; - Dy += h2; - - // Extract integer and fractions of source screen coordinates - int xc = (int)Dx; - Dx -= (double)xc; - xc -= sx; - int yc = (int)Dy; - Dy -= (double)yc; - yc -= sy; - - // Convert only valid pixels - if (yc >= 0 && yc < original->getHeight() && xc >= 0 && xc < original->getWidth()) { - - // multiplier for vignetting correction - double vignmul = 1.0; - - if (needsVignetting()) { - if (darkening) { - vignmul /= std::max (v + mul * tanh (b * (maxRadius - s * r2) / maxRadius), 0.001); + // multiplier for vignetting correction + if (yc > 0 && yc < original->getHeight() - 2 && xc > 0 && xc < original->getWidth() - 2) { + // all interpolation pixels inside image + interpolateTransformChannelsCubic (chOrig[c], xc - 1, yc - 1, Dx, Dy, & (chTrans[c][y][x]), 1.0); } else { - vignmul = v + mul * tanh (b * (maxRadius - s * r2) / maxRadius); + // edge pixels + int y1 = LIM (yc, 0, original->getHeight() - 1); + int y2 = LIM (yc + 1, 0, original->getHeight() - 1); + int x1 = LIM (xc, 0, original->getWidth() - 1); + int x2 = LIM (xc + 1, 0, original->getWidth() - 1); + + chTrans[c][y][x] = (chOrig[c][y1][x1] * (1.0 - Dx) * (1.0 - Dy) + chOrig[c][y1][x2] * Dx * (1.0 - Dy) + chOrig[c][y2][x1] * (1.0 - Dx) * Dy + chOrig[c][y2][x2] * Dx * Dy); } - } - - if (needsGradient()) { - vignmul *= calcGradientFactor (gp, cx + x, cy + y); - } - - if (needsPCVignetting()) { - vignmul *= calcPCVignetteFactor (pcv, cx + x, cy + y); - } - - if (yc < original->getHeight() - 1 && xc < original->getWidth() - 1) { - // all interpolation pixels inside image - transformed->r (y, x) = vignmul * (original->r (yc, xc) * (1.0 - Dx) * (1.0 - Dy) + original->r (yc, xc + 1) * Dx * (1.0 - Dy) + original->r (yc + 1, xc) * (1.0 - Dx) * Dy + original->r (yc + 1, xc + 1) * Dx * Dy); - transformed->g (y, x) = vignmul * (original->g (yc, xc) * (1.0 - Dx) * (1.0 - Dy) + original->g (yc, xc + 1) * Dx * (1.0 - Dy) + original->g (yc + 1, xc) * (1.0 - Dx) * Dy + original->g (yc + 1, xc + 1) * Dx * Dy); - transformed->b (y, x) = vignmul * (original->b (yc, xc) * (1.0 - Dx) * (1.0 - Dy) + original->b (yc, xc + 1) * Dx * (1.0 - Dy) + original->b (yc + 1, xc) * (1.0 - Dx) * Dy + original->b (yc + 1, xc + 1) * Dx * Dy); } else { - // edge pixels - int y1 = LIM (yc, 0, original->getHeight() - 1); - int y2 = LIM (yc + 1, 0, original->getHeight() - 1); - int x1 = LIM (xc, 0, original->getWidth() - 1); - int x2 = LIM (xc + 1, 0, original->getWidth() - 1); - transformed->r (y, x) = vignmul * (original->r (y1, x1) * (1.0 - Dx) * (1.0 - Dy) + original->r (y1, x2) * Dx * (1.0 - Dy) + original->r (y2, x1) * (1.0 - Dx) * Dy + original->r (y2, x2) * Dx * Dy); - transformed->g (y, x) = vignmul * (original->g (y1, x1) * (1.0 - Dx) * (1.0 - Dy) + original->g (y1, x2) * Dx * (1.0 - Dy) + original->g (y2, x1) * (1.0 - Dx) * Dy + original->g (y2, x2) * Dx * Dy); - transformed->b (y, x) = vignmul * (original->b (y1, x1) * (1.0 - Dx) * (1.0 - Dy) + original->b (y1, x2) * Dx * (1.0 - Dy) + original->b (y2, x1) * (1.0 - Dx) * Dy + original->b (y2, x2) * Dx * Dy); + // not valid (source pixel x,y not inside source image, etc.) + chTrans[c][y][x] = 0; } - } else { - // not valid (source pixel x,y not inside source image, etc.) - transformed->r (y, x) = 0; - transformed->g (y, x) = 0; - transformed->b (y, x) = 0; } } } } -double ImProcFunctions::getTransformAutoFill (int oW, int oH, const LCPMapper *pLCPMap) + +double ImProcFunctions::getTransformAutoFill (int oW, int oH, const LensCorrection *pLCPMap) { if (!needsCA() && !needsDistortion() && !needsRotation() && !needsPerspective() && (!params->lensProf.useDist || pLCPMap == nullptr)) { return 1; @@ -1150,12 +1063,17 @@ bool ImProcFunctions::needsVignetting () bool ImProcFunctions::needsLCP () { - return params->lensProf.lcpFile.length() > 0; + return params->lensProf.useLcp(); +} + +bool ImProcFunctions::needsLensfun() +{ + return params->lensProf.useLensfun(); } bool ImProcFunctions::needsTransform () { - return needsCA () || needsDistortion () || needsRotation () || needsPerspective () || needsGradient () || needsPCVignetting () || needsVignetting () || needsLCP(); + return needsCA () || needsDistortion () || needsRotation () || needsPerspective () || needsGradient () || needsPCVignetting () || needsVignetting () || needsLCP() || needsLensfun(); } diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index a5c9b6d7a..85b35ef18 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -140,7 +140,7 @@ struct cont_params { int wavNestedLevels = 1; -SSEFUNCTION 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, bool wavcontlutili, int skip) +SSEFUNCTION 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) { @@ -669,12 +669,12 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int #pragma omp parallel num_threads(numthreads) #endif { - float *mean = new float [9]; - float *meanN = new float [9]; - float *sigma = new float [9]; - float *sigmaN = new float [9]; - float *MaxP = new float [9]; - float *MaxN = new float [9]; + float mean[10]; + float meanN[10]; + float sigma[10]; + float sigmaN[10]; + float MaxP[10]; + float MaxN[10]; float** varhue = new float*[tileheight]; @@ -883,7 +883,6 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int } } - int ind = 0; bool ref = false; if((cp.lev0s > 0.f || cp.lev1s > 0.f || cp.lev2s > 0.f || cp.lev3s > 0.f) && cp.noiseena) { @@ -899,7 +898,7 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int } if(cp.val > 0 || ref || contr) {//edge - Evaluate2(*Ldecomp, cp, ind, mean, meanN, sigma, sigmaN, MaxP, MaxN, madL); + Evaluate2(*Ldecomp, mean, meanN, sigma, sigmaN, MaxP, MaxN); } //init for edge and denoise @@ -921,7 +920,6 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL, vari, edge); } - ind = 1; //Flat curve for Contrast=f(H) in levels FlatCurve* ChCurve = new FlatCurve(params->wavelet.Chcurve); //curve C=f(H) bool Chutili = false; @@ -936,10 +934,10 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int } - WaveletcontAllL(labco, varhue, varchro, *Ldecomp, cp, skip, mean, meanN, sigma, sigmaN, MaxP, MaxN, wavCLVCcurve, waOpacityCurveW, waOpacityCurveWL, 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 - Evaluate2(*Ldecomp, cp, ind, mean, meanN, sigma, sigmaN, MaxP, MaxN, madL); + Evaluate2(*Ldecomp, mean, meanN, sigma, sigmaN, MaxP, MaxN); } WaveletcontAllLfinal(*Ldecomp, cp, mean, sigma, MaxP, waOpacityCurveWL); @@ -1025,7 +1023,7 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int if(!adecomp->memoryAllocationFailed && !bdecomp->memoryAllocationFailed) { WaveletcontAllAB(labco, varhue, varchro, *adecomp, waOpacityCurveW, cp, true); WaveletcontAllAB(labco, varhue, varchro, *bdecomp, waOpacityCurveW, cp, false); - WaveletAandBAllAB(labco, varhue, varchro, *adecomp, *bdecomp, cp, waOpacityCurveW, hhCurve, hhutili ); + WaveletAandBAllAB(*adecomp, *bdecomp, cp, hhCurve, hhutili ); adecomp->reconstruct(labco->data + datalen, cp.strength); bdecomp->reconstruct(labco->data + 2 * datalen, cp.strength); @@ -1247,12 +1245,6 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int delete [] varchro; - delete [] mean; - delete [] meanN; - delete [] sigma; - delete [] sigmaN; - delete [] MaxP; - delete [] MaxN; } #ifdef _RT_NESTED_OPENMP omp_set_nested(oldNested); @@ -1372,7 +1364,7 @@ void ImProcFunctions::Sigma( float * RESTRICT DataList, int datalen, float aver } void ImProcFunctions::Evaluate2(wavelet_decomposition &WaveletCoeffs_L, - const struct cont_params& cp, int ind, float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN, float madL[8][3]) + float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN) { //StopWatch Stop1("Evaluate2"); int maxlvl = WaveletCoeffs_L.maxlevel(); @@ -1382,16 +1374,14 @@ void ImProcFunctions::Evaluate2(wavelet_decomposition &WaveletCoeffs_L, int Wlvl_L = WaveletCoeffs_L.level_W(lvl); int Hlvl_L = WaveletCoeffs_L.level_H(lvl); - int skip_L = WaveletCoeffs_L.level_stride(lvl); - float ** WavCoeffs_L = WaveletCoeffs_L.level_coeffs(lvl); - Eval2 (WavCoeffs_L, lvl, cp, Wlvl_L, Hlvl_L, skip_L, ind, mean, meanN, sigma, sigmaN, MaxP, MaxN, madL[lvl]); + Eval2 (WavCoeffs_L, lvl, Wlvl_L, Hlvl_L, mean, meanN, sigma, sigmaN, MaxP, MaxN); } } -void ImProcFunctions::Eval2 (float ** WavCoeffs_L, int level, const struct cont_params& cp, - int W_L, int H_L, int skip_L, int ind, float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN, float *madL) +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]; @@ -1435,7 +1425,7 @@ void ImProcFunctions::Eval2 (float ** WavCoeffs_L, int level, const struct cont MaxN[level] = maxLN; } -float *ImProcFunctions::ContrastDR(float *Source, int skip, struct cont_params &cp, int W_L, int H_L, float Compression, float DetailBoost, float max0, float min0, float ave, float ah, float bh, float al, float bl, float factorx, float *Contrast) +float *ImProcFunctions::ContrastDR(float *Source, int W_L, int H_L, float *Contrast) { int n = W_L * H_L; @@ -1455,7 +1445,7 @@ float *ImProcFunctions::ContrastDR(float *Source, int skip, struct cont_params & return Contrast; } -SSEFUNCTION float *ImProcFunctions::CompressDR(float *Source, int skip, struct cont_params &cp, int W_L, int H_L, float Compression, float DetailBoost, float max0, float min0, float ave, float ah, float bh, float al, float bl, float factorx, float *Compressed) +SSEFUNCTION float *ImProcFunctions::CompressDR(float *Source, int W_L, int H_L, float Compression, float DetailBoost, float *Compressed) { const float eps = 0.000001f; @@ -1491,7 +1481,7 @@ SSEFUNCTION float *ImProcFunctions::CompressDR(float *Source, int skip, struct c #endif - float *ucr = ContrastDR(Source, skip, cp, W_L, H_L, Compression, DetailBoost, max0, min0, ave, ah, bh, al, bl, factorx); + float *ucr = ContrastDR(Source, W_L, H_L); if(Compressed == nullptr) { Compressed = ucr; @@ -1569,7 +1559,7 @@ SSEFUNCTION float *ImProcFunctions::CompressDR(float *Source, int skip, struct c } -void ImProcFunctions::ContrastResid(float * WavCoeffs_L0, unsigned int Iterates, int skip, struct cont_params &cp, int W_L, int H_L, float max0, float min0, float ave, float ah, float bh, float al, float bl, float factorx) +void ImProcFunctions::ContrastResid(float * WavCoeffs_L0, struct cont_params &cp, int W_L, int H_L, float max0, float min0) { float stren = cp.tmstrength; float gamm = params->wavelet.gamma; @@ -1599,7 +1589,7 @@ void ImProcFunctions::ContrastResid(float * WavCoeffs_L0, unsigned int Iterates } - CompressDR(WavCoeffs_L0, skip, cp, W_L, H_L, Compression, DetailBoost, max0, min0, ave, ah, bh, al, bl, factorx, WavCoeffs_L0); + CompressDR(WavCoeffs_L0, W_L, H_L, Compression, DetailBoost, WavCoeffs_L0); #ifdef _RT_NESTED_OPENMP @@ -1685,7 +1675,7 @@ void ImProcFunctions::WaveletcontAllLfinal(wavelet_decomposition &WaveletCoeffs_ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float **varchrom, wavelet_decomposition &WaveletCoeffs_L, - struct cont_params &cp, int skip, float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveWL & waOpacityCurveWL, FlatCurve* ChCurve, bool Chutili) + 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); @@ -1830,7 +1820,7 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * #ifdef _RT_NESTED_OPENMP #pragma omp single #endif - ContrastResid(WavCoeffs_L0, 5, skip, cp, W_L, H_L, maxp, minp, ave, ah, bh, al, bl, factorx ); + ContrastResid(WavCoeffs_L0, cp, W_L, H_L, maxp, minp); } #ifdef _RT_NESTED_OPENMP @@ -2038,7 +2028,7 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * 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, meanN, sigma, sigmaN, 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); } @@ -2051,8 +2041,8 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * } } -void ImProcFunctions::WaveletAandBAllAB(LabImage * labco, float ** varhue, float **varchrom, wavelet_decomposition &WaveletCoeffs_a, wavelet_decomposition &WaveletCoeffs_b, - struct cont_params &cp, const WavOpacityCurveW & waOpacityCurveW, FlatCurve* hhCurve, bool hhutili) +void ImProcFunctions::WaveletAandBAllAB(wavelet_decomposition &WaveletCoeffs_a, wavelet_decomposition &WaveletCoeffs_b, + struct cont_params &cp, FlatCurve* hhCurve, bool hhutili) { // StopWatch Stop1("WaveletAandBAllAB"); if (hhutili && cp.resena) { // H=f(H) @@ -2579,7 +2569,7 @@ 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 *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, FlatCurve* ChCurve, bool Chutili) + 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); diff --git a/rtengine/labimage.cc b/rtengine/labimage.cc index 36d3e0f67..bcadda0ed 100644 --- a/rtengine/labimage.cc +++ b/rtengine/labimage.cc @@ -1,9 +1,31 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2017 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 + #include "labimage.h" -#include + namespace rtengine { -LabImage::LabImage (int w, int h) : fromImage(false), W(w), H(h) +LabImage::LabImage (int w, int h) : W(w), H(h) { allocLab(w, h); } @@ -42,4 +64,43 @@ void LabImage::getPipetteData (float &v1, float &v2, float &v3, int posX, int po v3 = n ? accumulator_b / float(n) : 0.f; } +void LabImage::allocLab(int w, int h) +{ + L = new float*[h]; + a = new float*[h]; + b = new float*[h]; + + data = new float [w * h * 3]; + float * index = data; + + for (int i = 0; i < h; i++) { + L[i] = index + i * w; + } + + index += w * h; + + for (int i = 0; i < h; i++) { + a[i] = index + i * w; + } + + index += w * h; + + for (int i = 0; i < h; i++) { + b[i] = index + i * w; + } +} + +void LabImage::deleteLab() +{ + delete [] L; + delete [] a; + delete [] b; + delete [] data; +} + +void LabImage::reallocLab() +{ + allocLab(W, H); +}; + } diff --git a/rtengine/labimage.h b/rtengine/labimage.h index 4b7db93c0..93f3887b6 100644 --- a/rtengine/labimage.h +++ b/rtengine/labimage.h @@ -25,32 +25,8 @@ namespace rtengine class LabImage { private: - bool fromImage; - void allocLab(int w, int h) - { - L = new float*[H]; - a = new float*[H]; - b = new float*[H]; + void allocLab(int w, int h); - data = new float [W * H * 3]; - float * index = data; - - for (int i = 0; i < H; i++) { - L[i] = index + i * W; - } - - index += W * H; - - for (int i = 0; i < H; i++) { - a[i] = index + i * W; - } - - index += W * H; - - for (int i = 0; i < H; i++) { - b[i] = index + i * W; - } - }; public: int W, H; float * data; @@ -64,20 +40,8 @@ public: //Copies image data in Img into this instance. void CopyFrom(LabImage *Img); void getPipetteData (float &L, float &a, float &b, int posX, int posY, int squareSize); - void deleteLab( ) - { - if (!fromImage) { - delete [] L; - delete [] a; - delete [] b; - delete [] data; - } - } - void reallocLab( ) - { - allocLab(W, H); - }; - + void deleteLab(); + void reallocLab(); }; } diff --git a/rtengine/lcp.cc b/rtengine/lcp.cc index c09d2d9be..15e68d9f1 100644 --- a/rtengine/lcp.cc +++ b/rtengine/lcp.cc @@ -20,27 +20,43 @@ #include #include -#include "lcp.h" #include #ifdef WIN32 -#include #include +#include #endif +#include "lcp.h" + #include "settings.h" -using namespace std; -using namespace rtengine; - - -namespace rtengine { +namespace rtengine +{ extern const Settings* settings; } -LCPModelCommon::LCPModelCommon() : +class rtengine::LCPProfile::LCPPersModel +{ +public: + LCPPersModel(); + bool hasModeData(LCPCorrectionMode mode) const; + void print() const; + + float focLen; + float focDist; + float aperture; // this is what it refers to + + LCPModelCommon base; // base perspective correction + LCPModelCommon chromRG; + LCPModelCommon chromG; + LCPModelCommon chromBG; // red/green, green, blue/green (may be empty) + LCPModelCommon vignette; // vignette (may be empty) +}; + +rtengine::LCPModelCommon::LCPModelCommon() : foc_len_x(-1.0f), foc_len_y(-1.0f), img_center_x(0.5f), @@ -59,20 +75,23 @@ LCPModelCommon::LCPModelCommon() : { } -bool LCPModelCommon::empty() const +bool rtengine::LCPModelCommon::empty() const { - return param[0] == 0.0f && param[1] == 0.0f && param[2] == 0.0f; + return + param[0] == 0.0f + && param[1] == 0.0f + && param[2] == 0.0f; } -void LCPModelCommon::print() const +void rtengine::LCPModelCommon::print() const { - 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); - printf("xy0 %g/%g fxy %g/%g\n", x0, y0, fx, fy); - printf("param: %g/%g/%g/%g/%g\n", param[0], param[1], param[2], param[3], param[4]); + 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 LCPModelCommon::merge(const LCPModelCommon& a, const LCPModelCommon& b, float facA) +void rtengine::LCPModelCommon::merge(const LCPModelCommon& a, const LCPModelCommon& b, float facA) { const float facB = 1.0f - facA; @@ -83,7 +102,7 @@ void LCPModelCommon::merge(const LCPModelCommon& a, const LCPModelCommon& b, flo scale_factor = facA * a.scale_factor + facB * b.scale_factor; mean_error = facA * a.mean_error + facB * b.mean_error; - for (int i = 0; i < 5; i++) { + for (int i = 0; i < 5; ++i) { param[i] = facA * a.param[i] + facB * b.param[i]; } @@ -96,7 +115,16 @@ void LCPModelCommon::merge(const LCPModelCommon& a, const LCPModelCommon& b, flo } -void LCPModelCommon::prepareParams(int fullWidth, int fullHeight, float focalLength, float focalLength35mm, float sensorFormatFactor, bool swapXY, bool mirrorX, bool mirrorY) +void rtengine::LCPModelCommon::prepareParams( + int fullWidth, + int fullHeight, + float focalLength, + float focalLength35mm, + float sensorFormatFactor, + bool swapXY, + bool mirrorX, + bool mirrorY +) { // Mention that the Adobe technical paper has a bug here, the DMAX is handled differently for focLen and imgCenter const int Dmax = std::max(fullWidth, fullHeight); @@ -125,60 +153,842 @@ void LCPModelCommon::prepareParams(int fullWidth, int fullHeight, float focalLen rfx = 1.0f / fx; rfy = 1.0f / fy; - //printf("FW %i /X0 %g FH %i /Y0 %g %g\n",fullWidth,x0,fullHeight,y0, imgYCenter); + //std::printf("FW %i /X0 %g FH %i /Y0 %g %g\n",fullWidth,x0,fullHeight,y0, imgYCenter); } -LCPPersModel::LCPPersModel() +rtengine::LCPProfile::LCPPersModel::LCPPersModel() : + focLen(0.f), + focDist(0.f), + aperture(0.f) { - focLen = focDist = aperture = 0; } -// mode: 0=distortion, 1=vignette, 2=CA -bool LCPPersModel::hasModeData(int mode) const +bool rtengine::LCPProfile::LCPPersModel::hasModeData(LCPCorrectionMode mode) const { - return (mode == 0 && !vignette.empty() && !vignette.bad_error) || (mode == 1 && !base.empty() && !base.bad_error) - || (mode == 2 && !chromRG.empty() && !chromG.empty() && !chromBG.empty() && - !chromRG.bad_error && !chromG.bad_error && !chromBG.bad_error); + switch (mode) { + case LCPCorrectionMode::VIGNETTE: { + return !vignette.empty() && !vignette.bad_error; + } + + case LCPCorrectionMode::DISTORTION: { + return !base.empty() && !base.bad_error; + } + + case LCPCorrectionMode::CA: { + return + !chromRG.empty() + && !chromG.empty() + && !chromBG.empty() + && !chromRG.bad_error + && !chromG.bad_error + && !chromBG.bad_error; + } + } + + assert(false); + return false; } -void LCPPersModel::print() const +void rtengine::LCPProfile::LCPPersModel::print() const { - printf("--- PersModel focLen %g; focDist %g; aperture %g\n", focLen, focDist, aperture); - printf("Base:\n"); + std::printf("--- PersModel focLen %g; focDist %g; aperture %g\n", focLen, focDist, aperture); + std::printf("Base:\n"); base.print(); if (!chromRG.empty()) { - printf("ChromRG:\n"); + std::printf("ChromRG:\n"); chromRG.print(); } if (!chromG.empty()) { - printf("ChromG:\n"); + std::printf("ChromG:\n"); chromG.print(); } if (!chromBG.empty()) { - printf("ChromBG:\n"); + std::printf("ChromBG:\n"); chromBG.print(); } if (!vignette.empty()) { - printf("Vignette:\n"); + std::printf("Vignette:\n"); vignette.print(); } - printf("\n"); + std::printf("\n"); } -// if !vignette then geometric and CA -LCPMapper::LCPMapper(LCPProfile* pProf, float focalLength, float focalLength35mm, float focusDist, float aperture, bool vignette, bool useCADistP, - int fullWidth, int fullHeight, const CoarseTransformParams& coarse, int rawRotationDeg) :useCADist(false), swapXY(false), isFisheye(false), enableCA(false) +rtengine::LCPProfile::LCPProfile(const Glib::ustring& fname) : + isFisheye(false), + sensorFormatFactor(1.f), + persModelCount(0), + inCamProfiles(false), + firstLIDone(false), + inPerspect(false), + inAlternateLensID(false), + inAlternateLensNames(false), + lastTag{}, + inInvalidTag{}, + pCurPersModel(nullptr), + pCurCommon(nullptr), + aPersModel{} { - if (pProf == nullptr) { + const int BufferSize = 8192; + char buf[BufferSize]; + + XML_Parser parser = XML_ParserCreate(nullptr); + + if (!parser) { + throw "Couldn't allocate memory for XML parser"; + } + + XML_SetElementHandler(parser, XmlStartHandler, XmlEndHandler); + XML_SetCharacterDataHandler(parser, XmlTextHandler); + XML_SetUserData(parser, static_cast(this)); + + FILE* const pFile = g_fopen(fname.c_str (), "rb"); + + if (pFile) { + bool done; + + do { + int bytesRead = fread(buf, 1, BufferSize, pFile); + done = feof(pFile); + + if (XML_Parse(parser, buf, bytesRead, done) == XML_STATUS_ERROR) { + XML_ParserFree(parser); + throw "Invalid XML in LCP file"; + } + } while (!done); + + fclose(pFile); + } + + XML_ParserFree(parser); + + if (settings->verbose) { + std::printf("Parsing %s\n", fname.c_str()); + } + // Two phase filter: first filter out the very rough ones, that distord the average a lot + // force it, even if there are few frames (community profiles) + filterBadFrames(LCPCorrectionMode::VIGNETTE, 2.0, 0); + filterBadFrames(LCPCorrectionMode::CA, 2.0, 0); + // from the non-distorded, filter again on new average basis, but only if there are enough frames left + filterBadFrames(LCPCorrectionMode::VIGNETTE, 1.5, 50); + filterBadFrames(LCPCorrectionMode::CA, 1.5, 50); +} + +rtengine::LCPProfile::~LCPProfile() +{ + delete pCurPersModel; + + for (int i = 0; i < MaxPersModelCount; ++i) { + delete aPersModel[i]; + } +} + +void rtengine::LCPProfile::calcParams( + LCPCorrectionMode mode, + float focalLength, + float focusDist, + float aperture, + LCPModelCommon* pCorr1, + LCPModelCommon* pCorr2, + LCPModelCommon* pCorr3 +) const +{ + const float euler = std::exp(1.0); + + // find the frames with the least distance, focal length wise + LCPPersModel* pLow = nullptr; + LCPPersModel* pHigh = nullptr; + + const float focalLengthLog = std::log(focalLength); //, apertureLog=aperture>0 ? std::log(aperture) : 0; + const float focusDistLog = focusDist > 0 ? std::log(focusDist) + euler : 0; + + // Pass 1: determining best focal length, if possible different focusDistances (for the focDist is not given case) + for (int pm = 0; pm < persModelCount; ++pm) { + const float f = aPersModel[pm]->focLen; + + if (aPersModel[pm]->hasModeData(mode)) { + if ( + f <= focalLength + && ( + pLow == nullptr + || f > pLow->focLen + || ( + focusDist == 0 + && f == pLow->focLen + && pLow->focDist > aPersModel[pm]->focDist + ) + ) + ) { + pLow = aPersModel[pm]; + } + + if ( + f >= focalLength + && ( + pHigh == nullptr + || f < pHigh->focLen + || ( + focusDist == 0 + && f == pHigh->focLen + && pHigh->focDist < aPersModel[pm]->focDist + ) + ) + ) { + pHigh = aPersModel[pm]; + } + } + } + + if (!pLow) { + pLow = pHigh; + } + else if (!pHigh) { + pHigh = pLow; + } + else { + // Pass 2: We have some, so take the best aperture for vignette and best focus for CA and distortion + // there are usually several frame per focal length. In the end pLow will have both flen and apterure/focdis below the target, + // and vice versa pHigh + const float bestFocLenLow = pLow->focLen; + const float bestFocLenHigh = pHigh->focLen; + + for (int pm = 0; pm < persModelCount; ++pm) { + const float aper = aPersModel[pm]->aperture; // float aperLog=std::log(aper); + const float focDist = aPersModel[pm]->focDist; + const float focDistLog = std::log(focDist) + euler; + + double meanErr; + + if (aPersModel[pm]->hasModeData(mode)) { + double lowMeanErr = 0.0; + double highMeanErr = 0.0; + + switch (mode) { + case LCPCorrectionMode::VIGNETTE: { + meanErr = aPersModel[pm]->vignette.mean_error; + lowMeanErr = pLow->vignette.mean_error; + highMeanErr = pHigh->vignette.mean_error; + break; + } + + case LCPCorrectionMode::DISTORTION: { + meanErr = aPersModel[pm]->base.mean_error; + lowMeanErr = pLow->base.mean_error; + highMeanErr = pHigh->base.mean_error; + break; + } + + case LCPCorrectionMode::CA: { + meanErr = aPersModel[pm]->chromG.mean_error; + lowMeanErr = pLow->chromG.mean_error; + highMeanErr = pHigh->chromG.mean_error; + break; + } + } + + if (aperture > 0 && mode != LCPCorrectionMode::CA) { + if ( + aPersModel[pm]->focLen == bestFocLenLow + && ( + ( + aper == aperture + && lowMeanErr > meanErr + ) + || ( + aper >= aperture + && aper < pLow->aperture + && pLow->aperture > aperture + ) + || ( + aper <= aperture + && ( + pLow->aperture > aperture + || fabs(aperture - aper) < fabs(aperture - pLow->aperture) + ) + ) + ) + ) { + pLow = aPersModel[pm]; + } + + if ( + aPersModel[pm]->focLen == bestFocLenHigh + && ( + ( + aper == aperture + && highMeanErr > meanErr + ) + || ( + aper <= aperture + && aper > pHigh->aperture + && pHigh->aperture < aperture + ) + || ( + aper >= aperture + && ( + pHigh->aperture < aperture + || fabs(aperture - aper) < fabs(aperture - pHigh->aperture) + ) + ) + ) + ) { + pHigh = aPersModel[pm]; + } + } + else if (focusDist > 0 && mode != LCPCorrectionMode::VIGNETTE) { + // by focus distance + if ( + aPersModel[pm]->focLen == bestFocLenLow + && ( + ( + focDist == focusDist + && lowMeanErr > meanErr + ) + || ( + focDist >= focusDist + && focDist < pLow->focDist + && pLow->focDist > focusDist + ) + || ( + focDist <= focusDist + && ( + pLow->focDist > focusDist + || fabs(focusDistLog - focDistLog) < fabs(focusDistLog - (std::log(pLow->focDist) + euler)) + ) + ) + ) + ) { + pLow = aPersModel[pm]; + } + + if ( + aPersModel[pm]->focLen == bestFocLenHigh + && ( + ( + focDist == focusDist + && highMeanErr > meanErr + ) + || ( + focDist <= focusDist + && focDist > pHigh->focDist + && pHigh->focDist < focusDist + ) + || ( + focDist >= focusDist + && ( + pHigh->focDist < focusDist + || fabs(focusDistLog - focDistLog) < fabs(focusDistLog - (std::log(pHigh->focDist) + euler)) + ) + ) + ) + ) { + pHigh = aPersModel[pm]; + } + } + else { + // no focus distance available, just error + if (aPersModel[pm]->focLen == bestFocLenLow && lowMeanErr > meanErr) { + pLow = aPersModel[pm]; + } + + if (aPersModel[pm]->focLen == bestFocLenHigh && highMeanErr > meanErr) { + pHigh = aPersModel[pm]; + } + } + + } + } + } + + if (pLow != nullptr && pHigh != nullptr) { + // average out the factors, linear interpolation in logarithmic scale + float facLow = 0.5f; + bool focLenOnSpot = false; // pretty often, since max/min are often as frames in LCP + + // There is as foclen range, take that as basis + if (pLow->focLen < pHigh->focLen) { + facLow = (std::log(pHigh->focLen) - focalLengthLog) / (std::log(pHigh->focLen) - std::log(pLow->focLen)); + } else { + focLenOnSpot = pLow->focLen == pHigh->focLen && pLow->focLen == focalLength; + } + + // and average the other factor if available + if ( + mode == LCPCorrectionMode::VIGNETTE + && pLow->aperture < aperture + && pHigh->aperture > aperture + ) { + // Mix in aperture + const float facAperLow = (pHigh->aperture - aperture) / (pHigh->aperture - pLow->aperture); + facLow = focLenOnSpot ? facAperLow : (0.5 * facLow + 0.5 * facAperLow); + } + else if ( + mode != LCPCorrectionMode::VIGNETTE + && focusDist > 0 + && pLow->focDist < focusDist + && pHigh->focDist > focusDist + ) { + // 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); + } + + switch (mode) { + case LCPCorrectionMode::VIGNETTE: { + pCorr1->merge(pLow->vignette, pHigh->vignette, facLow); + break; + } + + case LCPCorrectionMode::DISTORTION: { + pCorr1->merge(pLow->base, pHigh->base, facLow); + break; + } + + case LCPCorrectionMode::CA: { + pCorr1->merge(pLow->chromRG, pHigh->chromRG, facLow); + pCorr2->merge(pLow->chromG, pHigh->chromG, facLow); + pCorr3->merge(pLow->chromBG, pHigh->chromBG, facLow); + break; + } + } + + 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); + } + } else { + if (settings->verbose) { + std::printf("Error: LCP file contained no %s parameters\n", mode == LCPCorrectionMode::VIGNETTE ? "vignette" : mode == LCPCorrectionMode::DISTORTION ? "distortion" : "CA" ); + } + } +} + +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) +{ + // take average error, then calculated the maximum deviation allowed + double err = 0.0; + int count = 0; + + for (int pm = 0; pm < MaxPersModelCount && aPersModel[pm]; ++pm) { + if (aPersModel[pm]->hasModeData(mode)) { + ++count; + switch (mode) { + case LCPCorrectionMode::VIGNETTE: { + err += aPersModel[pm]->vignette.mean_error; + break; + } + + case LCPCorrectionMode::DISTORTION: { + err += aPersModel[pm]->base.mean_error; + break; + } + + case LCPCorrectionMode::CA: { + err += rtengine::max(aPersModel[pm]->chromRG.mean_error, aPersModel[pm]->chromG.mean_error, aPersModel[pm]->chromBG.mean_error); + break; + } + } + } + } + + // Only if we have enough frames, filter out errors + int filtered = 0; + + if (count >= minFramesLeft) { + if (count > 0) { + err /= count; + } + + // Now mark all the bad ones as bad, and hasModeData will return false; + for (int pm = 0; pm < MaxPersModelCount && aPersModel[pm]; ++pm) { + if (aPersModel[pm]->hasModeData(mode)) { + switch (mode) { + case LCPCorrectionMode::VIGNETTE: { + if (aPersModel[pm]->vignette.mean_error > maxAvgDevFac * err) { + aPersModel[pm]->vignette.bad_error = true; + filtered++; + } + break; + } + + case LCPCorrectionMode::DISTORTION: { + if (aPersModel[pm]->base.mean_error > maxAvgDevFac * err) { + aPersModel[pm]->base.bad_error = true; + filtered++; + } + break; + } + + case LCPCorrectionMode::CA: { + if ( + aPersModel[pm]->chromRG.mean_error > maxAvgDevFac * err + || aPersModel[pm]->chromG.mean_error > maxAvgDevFac * err + || aPersModel[pm]->chromBG.mean_error > maxAvgDevFac * err + ) { + aPersModel[pm]->chromRG.bad_error = true; + aPersModel[pm]->chromG.bad_error = true; + aPersModel[pm]->chromBG.bad_error = true; + ++filtered; + } + break; + } + } + } + } + + if (settings->verbose && count) { + std::printf("Filtered %.1f%% frames for maxAvgDevFac %g leaving %i\n", filtered * 100.f / count, maxAvgDevFac, count - filtered); + } + } + + return filtered; +} + +void rtengine::LCPProfile::handle_text(const std::string& text) +{ + // Check if it contains non-whitespaces (there are several calls to this for one tag unfortunately) + bool onlyWhiteSpace = true; + for (auto c : text) { + if (!std::isspace(c)) { + onlyWhiteSpace = false; + break; + } + } + + if (onlyWhiteSpace) { return; } - useCADist = useCADistP; + LCPProfile* const pProf = this; + + // convert to null terminated + const std::string tag = pProf->lastTag; + + // Common data section + if (!pProf->firstLIDone) { + // Generic tags are the same for all + if (tag == "ProfileName") { + pProf->profileName = text; + } else if (tag == "Model") { + pProf->camera = text; + } else if (tag == "Lens") { + pProf->lens = text; + } else if (tag == "CameraPrettyName") { + pProf->cameraPrettyName = text; + } else if (tag == "LensPrettyName") { + pProf->lensPrettyName = text; + } else if (tag == "CameraRawProfile") { + pProf->isRaw = text == "True"; + } + } + + // Locale should be already set + assert(std::atof("1.2345") == 1.2345); + + if (!pProf->firstLIDone) { + if (tag == "SensorFormatFactor") { + pProf->sensorFormatFactor = std::atof(text.c_str()); + } + } + + // Perspective model base data + if (tag == "FocalLength") { + pProf->pCurPersModel->focLen = std::atof(text.c_str()); + } else if (tag == "FocusDistance") { + double focDist = std::atof(text.c_str()); + pProf->pCurPersModel->focDist = focDist < 10000 ? focDist : 10000; + } else if (tag == "ApertureValue") { + pProf->pCurPersModel->aperture = std::atof(text.c_str()); + } + + // Section depended + if (tag == "FocalLengthX") { + pProf->pCurCommon->foc_len_x = std::atof(text.c_str()); + } else if (tag == "FocalLengthY") { + pProf->pCurCommon->foc_len_y = std::atof(text.c_str()); + } else if (tag == "ImageXCenter") { + pProf->pCurCommon->img_center_x = std::atof(text.c_str()); + } else if (tag == "ImageYCenter") { + pProf->pCurCommon->img_center_y = std::atof(text.c_str()); + } else if (tag == "ScaleFactor") { + pProf->pCurCommon->scale_factor = std::atof(text.c_str()); + } else if (tag == "ResidualMeanError") { + pProf->pCurCommon->mean_error = std::atof(text.c_str()); + } else if (tag == "RadialDistortParam1" || tag == "VignetteModelParam1") { + pProf->pCurCommon->param[0] = std::atof(text.c_str()); + } else if (tag == "RadialDistortParam2" || tag == "VignetteModelParam2") { + pProf->pCurCommon->param[1] = std::atof(text.c_str()); + } else if (tag == "RadialDistortParam3" || tag == "VignetteModelParam3") { + pProf->pCurCommon->param[2] = std::atof(text.c_str()); + } else if (tag == "RadialDistortParam4" || tag == "TangentialDistortParam1") { + pProf->pCurCommon->param[3] = std::atof(text.c_str()); + } else if (tag == "RadialDistortParam5" || tag == "TangentialDistortParam2") { + pProf->pCurCommon->param[4] = std::atof(text.c_str()); + } +} + +void XMLCALL rtengine::LCPProfile::XmlStartHandler(void* pLCPProfile, const char* el, const char** attr) +{ + LCPProfile* const pProf = static_cast(pLCPProfile); + + bool parseAttr = false; + + if (*pProf->inInvalidTag) { + return; // We ignore everything in dirty tag till it's gone + } + + // clean up tagname + const char* src = strrchr(el, ':'); + + if (src == nullptr) { + src = el; + } else { + ++src; + } + + strcpy(pProf->lastTag, src); + + const std::string src_str = src; + + if (src_str == "VignetteModelPiecewiseParam") { + strcpy(pProf->inInvalidTag, src); + } + + if (src_str == "CameraProfiles") { + pProf->inCamProfiles = true; + } + + if (src_str == "AlternateLensIDs") { + pProf->inAlternateLensID = true; + } + + if (src_str == "AlternateLensNames") { + pProf->inAlternateLensNames = true; + } + + if ( + !pProf->inCamProfiles + || pProf->inAlternateLensID + || pProf->inAlternateLensNames + ) { + return; + } + + if (src_str == "li") { + pProf->pCurPersModel = new LCPPersModel(); + pProf->pCurCommon = &pProf->pCurPersModel->base; // iterated to next tags within persModel + return; + } + + if (src_str == "PerspectiveModel") { + pProf->firstLIDone = true; + pProf->inPerspect = true; + parseAttr = true; + } else if (src_str == "FisheyeModel") { + pProf->firstLIDone = true; + pProf->inPerspect = true; + pProf->isFisheye = true; // just misses third param, and different path, rest is the same + parseAttr = true; + } else if (src_str == "Description") { + parseAttr = true; + } + + // Move pointer to general section + if (pProf->inPerspect) { + if (src_str == "ChromaticRedGreenModel") { + pProf->pCurCommon = &pProf->pCurPersModel->chromRG; + parseAttr = true; + } else if (src_str == "ChromaticGreenModel") { + pProf->pCurCommon = &pProf->pCurPersModel->chromG; + parseAttr = true; + } else if (src_str == "ChromaticBlueGreenModel") { + pProf->pCurCommon = &pProf->pCurPersModel->chromBG; + parseAttr = true; + } else if (src_str == "VignetteModel") { + pProf->pCurCommon = &pProf->pCurPersModel->vignette; + parseAttr = true; + } + } + + // some profiles (espc. Pentax) have a different structure that is attributes based + // simulate tags by feeding them in + if (parseAttr && attr != nullptr) { + for (int i = 0; attr[i]; i += 2) { + const char* nameStart = strrchr(attr[i], ':'); + + if (nameStart == nullptr) { + nameStart = attr[i]; + } else { + ++nameStart; + } + + strncpy(pProf->lastTag, nameStart, 255); + + pProf->handle_text(attr[i + 1]); + } + } +} + +void XMLCALL rtengine::LCPProfile::XmlTextHandler(void* pLCPProfile, const XML_Char* s, int len) +{ + LCPProfile* const pProf = static_cast(pLCPProfile); + + if ( + !pProf->inCamProfiles + || pProf->inAlternateLensID + || pProf->inAlternateLensNames + || *pProf->inInvalidTag + ) { + return; + } + + for (int i = 0; i < len; ++i) { + pProf->textbuf << s[i]; + } +} + +void XMLCALL rtengine::LCPProfile::XmlEndHandler(void* pLCPProfile, const char* el) +{ + LCPProfile* const pProf = static_cast(pLCPProfile); + + pProf->handle_text(pProf->textbuf.str()); + pProf->textbuf.str(""); + + // We ignore everything in dirty tag till it's gone + if (*pProf->inInvalidTag) { + if (std::strstr(el, pProf->inInvalidTag)) { + *pProf->inInvalidTag = 0; + } + + return; + } + + if (std::strstr(el, ":CameraProfiles")) { + pProf->inCamProfiles = false; + } + + if (std::strstr(el, ":AlternateLensIDs")) { + pProf->inAlternateLensID = false; + } + + if (std::strstr(el, ":AlternateLensNames")) { + pProf->inAlternateLensNames = false; + } + + if ( + !pProf->inCamProfiles + || pProf->inAlternateLensID + || pProf->inAlternateLensNames + ) { + return; + } + + if (std::strstr(el, ":PerspectiveModel") || std::strstr(el, ":FisheyeModel")) { + pProf->inPerspect = false; + } else if (std::strstr(el, ":li")) { + pProf->aPersModel[pProf->persModelCount] = pProf->pCurPersModel; + pProf->pCurPersModel = nullptr; + ++pProf->persModelCount; + } +} + +// Generates as singleton +rtengine::LCPStore* rtengine::LCPStore::getInstance() +{ + static LCPStore instance_; + return &instance_; +} + +bool rtengine::LCPStore::isValidLCPFileName(const Glib::ustring& filename) const +{ + if (!Glib::file_test(filename, Glib::FILE_TEST_EXISTS) || Glib::file_test (filename, Glib::FILE_TEST_IS_DIR)) { + return false; + } + + const size_t pos = filename.find_last_of ('.'); + return pos > 0 && !filename.casefold().compare(pos, 4, ".lcp"); +} + +std::shared_ptr rtengine::LCPStore::getProfile(const Glib::ustring& filename) const +{ + if (filename.length() == 0 || !isValidLCPFileName(filename)) { + return nullptr; + } + + std::shared_ptr res; + if (!cache.get(filename, res)) { + res.reset(new LCPProfile(filename)); + cache.set(filename, res); + } + + return res; +} + +Glib::ustring rtengine::LCPStore::getDefaultCommonDirectory() const +{ + Glib::ustring dir; + +#ifdef WIN32 + WCHAR pathW[MAX_PATH] = {0}; + + if (SHGetSpecialFolderPathW(NULL, pathW, CSIDL_COMMON_APPDATA, false)) { + char pathA[MAX_PATH]; + WideCharToMultiByte(CP_UTF8, 0, pathW, -1, pathA, MAX_PATH, 0, 0); + Glib::ustring fullDir = Glib::ustring(pathA) + Glib::ustring("\\Adobe\\CameraRaw\\LensProfiles\\1.0"); + + if (Glib::file_test (fullDir, Glib::FILE_TEST_IS_DIR)) { + dir = fullDir; + } + } + +#endif + + // TODO: Add Mac paths here + + return dir; +} + +rtengine::LCPStore::LCPStore(unsigned int _cache_size) : + cache(_cache_size) +{ +} + +// if !vignette then geometric and CA +rtengine::LCPMapper::LCPMapper( + const std::shared_ptr& pProf, + float focalLength, + float focalLength35mm, + float focusDist, + float aperture, + bool vignette, + bool useCADistP, + int fullWidth, + int fullHeight, + const CoarseTransformParams& coarse, + int rawRotationDeg +) : + enableCA(false), + useCADist(useCADistP), + swapXY(false), + isFisheye(false) +{ + if (!pProf) { + return; + } // determine in what the image with the RAW landscape in comparison (calibration target) // in vignetting, the rotation has not taken place yet @@ -188,84 +998,100 @@ LCPMapper::LCPMapper(LCPProfile* pProf, float focalLength, float focalLength35mm rot = (coarse.rotate + rawRotationDeg) % 360; } - swapXY = (rot == 90 || rot == 270); - bool mirrorX = (rot == 90 || rot == 180); - bool mirrorY = (rot == 180 || rot == 270); + swapXY = (rot == 90 || rot == 270); + + const bool mirrorX = (rot == 90 || rot == 180); + const bool mirrorY = (rot == 180 || rot == 270); if (settings->verbose) { - 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, focalLength, swapXY, mirrorX, mirrorY, rot, rawRotationDeg); } - pProf->calcParams(vignette ? 0 : 1, focalLength, focusDist, aperture, &mc, nullptr, nullptr); + pProf->calcParams(vignette ? LCPCorrectionMode::VIGNETTE : LCPCorrectionMode::DISTORTION, focalLength, focusDist, aperture, &mc, nullptr, nullptr); mc.prepareParams(fullWidth, fullHeight, focalLength, focalLength35mm, pProf->sensorFormatFactor, swapXY, mirrorX, mirrorY); if (!vignette) { - pProf->calcParams(2, focalLength, focusDist, aperture, &chrom[0], &chrom[1], &chrom[2]); + pProf->calcParams(LCPCorrectionMode::CA, focalLength, focusDist, aperture, &chrom[0], &chrom[1], &chrom[2]); - for (int i = 0; i < 3; i++) { + for (int i = 0; i < 3; ++i) { chrom[i].prepareParams(fullWidth, fullHeight, focalLength, focalLength35mm, pProf->sensorFormatFactor, swapXY, mirrorX, mirrorY); } } - enableCA = !vignette && focusDist > 0; + enableCA = !vignette && focusDist > 0.f; isFisheye = pProf->isFisheye; } -void LCPMapper::correctDistortion(double& x, double& y, double scale) const +bool rtengine::LCPMapper::isCACorrectionAvailable() const { + return enableCA; +} + +void rtengine::LCPMapper::correctDistortion(double &x, double &y, int cx, int cy, double scale) const +{ + x += cx; + y += cy; + if (isFisheye) { - double u = x * scale; - double v = y * scale; - double u0 = mc.x0 * scale; - double v0 = mc.y0 * scale; - double du = (u - u0); - double dv = (v - v0); - double fx = mc.fx; - double fy = mc.fy; - double k1 = mc.param[0]; - double k2 = mc.param[1]; - double r = sqrt(du * du + dv * dv); - double f = sqrt(fx*fy / (scale * scale)); - double th = atan2(r, f); - double th2 = th * th; - double cfact = (((k2 * th2 + k1) * th2 + 1) * th) / r; - double ud = cfact * fx * du + u0; - double vd = cfact * fy * dv + v0; + const double u = x * scale; + const double v = y * scale; + const double u0 = mc.x0 * scale; + const double v0 = mc.y0 * scale; + const double du = (u - u0); + const double dv = (v - v0); + const double fx = mc.fx; + const double fy = mc.fy; + const double k1 = mc.param[0]; + const double k2 = mc.param[1]; + const double r = sqrt(du * du + dv * dv); + const double f = sqrt(fx*fy / (scale * scale)); + const double th = atan2(r, f); + const double th2 = th * th; + const double cfact = (((k2 * th2 + k1) * th2 + 1) * th) / r; + const double ud = cfact * fx * du + u0; + const double vd = cfact * fy * dv + v0; x = ud; y = vd; } else { x *= scale; y *= scale; - double x0 = mc.x0 * scale; - double y0 = mc.y0 * scale; - double xd = (x - x0) / mc.fx, yd = (y - y0) / mc.fy; + 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 LCPModelCommon::Param aDist = mc.param; - double rsqr = xd * xd + yd * yd; - double xfac = aDist[swapXY ? 3 : 4], yfac = aDist[swapXY ? 4 : 3]; + const double rsqr = xd * xd + yd * yd; + const double xfac = aDist[swapXY ? 3 : 4], yfac = aDist[swapXY ? 4 : 3]; - double commonFac = (((aDist[2] * rsqr + aDist[1]) * rsqr + aDist[0]) * rsqr + 1.) + const double commonFac = (((aDist[2] * rsqr + aDist[1]) * rsqr + aDist[0]) * rsqr + 1.) + 2. * (yfac * yd + xfac * xd); - double xnew = xd * commonFac + xfac * rsqr; - double ynew = yd * commonFac + yfac * rsqr; + 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 -= cx * scale; + y -= cy * scale; } -void LCPMapper::correctCA(double& x, double& y, int channel) const +void rtengine::LCPMapper::correctCA(double& x, double& y, int cx, int cy, int channel) const { if (!enableCA) { return; } - double rsqr, xgreen, ygreen; + x += cx; + y += cy; + + double xgreen, ygreen; // First calc the green channel like normal distortion // the other are just deviations from it - double xd = (x - chrom[1].x0) / chrom[1].fx, yd = (y - chrom[1].y0) / chrom[1].fy; + double xd = (x - chrom[1].x0) / chrom[1].fx; + double yd = (y - chrom[1].y0) / chrom[1].fy; // Green contains main distortion, just like base if (useCADist) { @@ -291,18 +1117,21 @@ void LCPMapper::correctCA(double& x, double& y, int channel) const // others are diffs from green xd = xgreen; yd = ygreen; - rsqr = xd * xd + yd * yd; + const double rsqr = xd * xd + yd * yd; const LCPModelCommon::Param aCA = chrom[channel].param; - double xfac = aCA[swapXY ? 3 : 4], yfac = aCA[swapXY ? 4 : 3]; - double commonSum = 1. + rsqr * (aCA[0] + rsqr * (aCA[1] + aCA[2] * rsqr)) + 2. * (yfac * yd + xfac * xd); + 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); 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 -= cx; + y -= cy; } -SSEFUNCTION void LCPMapper::processVignetteLine(int width, int y, float *line) const +SSEFUNCTION void rtengine::LCPMapper::processVignetteLine(int width, int y, float* line) const { // No need for swapXY, since vignette is in RAW and always before rotation float yd = ((float)y - mc.y0) * mc.rfy; @@ -321,9 +1150,9 @@ SSEFUNCTION void LCPMapper::processVignetteLine(int width, int y, float *line) c vfloat xv = _mm_setr_ps(0.f, 1.f, 2.f, 3.f); for (; x < width-3; x+=4) { - vfloat xdv = (xv - x0v) * rfxv; - vfloat rsqr = xdv * xdv + ydv; - vfloat vignFactorv = rsqr * (p0 + rsqr * (p1 - p2 * rsqr + p3 * rsqr * rsqr)); + const vfloat xdv = (xv - x0v) * rfxv; + const vfloat rsqr = xdv * xdv + ydv; + const vfloat vignFactorv = rsqr * (p0 + rsqr * (p1 - p2 * rsqr + p3 * rsqr * rsqr)); vfloat valv = LVFU(line[x]); valv += valv * vselfzero(vmaskf_gt(valv, zerov), vignFactorv); STVFU(line[x], valv); @@ -332,24 +1161,24 @@ SSEFUNCTION void LCPMapper::processVignetteLine(int width, int y, float *line) c #endif // __SSE2__ for (; x < width; x++) { if (line[x] > 0) { - float xd = ((float)x - mc.x0) * mc.rfx; + const float xd = ((float)x - mc.x0) * mc.rfx; const LCPModelCommon::VignParam vignParam = mc.vign_param; - float rsqr = xd * xd + yd; + const float rsqr = xd * xd + yd; line[x] += line[x] * rsqr * (vignParam[0] + rsqr * ((vignParam[1]) - (vignParam[2]) * rsqr + (vignParam[3]) * rsqr * rsqr)); } } } -SSEFUNCTION void LCPMapper::processVignetteLine3Channels(int width, int y, float *line) const +SSEFUNCTION void rtengine::LCPMapper::processVignetteLine3Channels(int width, int y, float* line) const { // No need for swapXY, since vignette is in RAW and always before rotation float yd = ((float)y - mc.y0) * mc.rfy; yd *= yd; const LCPModelCommon::VignParam vignParam = mc.vign_param; for (int x = 0; x < width; x++) { - float xd = ((float)x - mc.x0) * mc.rfx; - float rsqr = xd * xd + yd; - float vignetteFactor = rsqr * (vignParam[0] + rsqr * ((vignParam[1]) - (vignParam[2]) * rsqr + (vignParam[3]) * rsqr * rsqr)); + const float xd = ((float)x - mc.x0) * mc.rfx; + const float rsqr = xd * xd + yd; + const float vignetteFactor = rsqr * (vignParam[0] + rsqr * ((vignParam[1]) - (vignParam[2]) * rsqr + (vignParam[3]) * rsqr * rsqr)); for(int c = 0;c < 3; ++c) { if (line[3*x+c] > 0) { line[3*x+c] += line[3*x+c] * vignetteFactor; @@ -357,623 +1186,3 @@ SSEFUNCTION void LCPMapper::processVignetteLine3Channels(int width, int y, float } } } - - -LCPProfile::LCPProfile(const Glib::ustring &fname) -{ - for (int i = 0; i < MaxPersModelCount; i++) { - aPersModel[i] = nullptr; - } - pCurPersModel = nullptr; - - const int BufferSize = 8192; - char buf[BufferSize]; - - XML_Parser parser = XML_ParserCreate(nullptr); - - if (!parser) { - throw "Couldn't allocate memory for XML parser"; - } - - XML_SetElementHandler(parser, XmlStartHandler, XmlEndHandler); - XML_SetCharacterDataHandler(parser, XmlTextHandler); - XML_SetUserData(parser, (void *)this); - - - isFisheye = inCamProfiles = firstLIDone = inPerspect = inAlternateLensID = inAlternateLensNames = false; - sensorFormatFactor = 1; - - persModelCount = 0; - *inInvalidTag = 0; - - FILE *pFile = g_fopen(fname.c_str (), "rb"); - - if(pFile) { - bool done; - - do { - int bytesRead = (int)fread(buf, 1, BufferSize, pFile); - done = feof(pFile); - - if (XML_Parse(parser, buf, bytesRead, done) == XML_STATUS_ERROR) { - throw "Invalid XML in LCP file"; - } - } while (!done); - - fclose(pFile); - } - - XML_ParserFree(parser); - - if (settings->verbose) { - printf("Parsing %s\n", fname.c_str()); - } - // Two phase filter: first filter out the very rough ones, that distord the average a lot - // force it, even if there are few frames (community profiles) -// filterBadFrames(2.0, 0); - // from the non-distorded, filter again on new average basis, but only if there are enough frames left -// filterBadFrames(1.5, 100); -} - - -LCPProfile::~LCPProfile() -{ - if (pCurPersModel) { - delete pCurPersModel; - } - for (int i = 0; i < MaxPersModelCount; i++) { - if (aPersModel[i]) { - delete aPersModel[i]; - } - } -} - -// 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 LCPProfile::filterBadFrames(double maxAvgDevFac, int minFramesLeft) -{ - // take average error per type, then calculated the maximum deviation allowed - double errBase = 0, errChrom = 0, errVignette = 0; - int baseCount = 0, chromCount = 0, vignetteCount = 0; - - for (int pm = 0; pm < MaxPersModelCount && aPersModel[pm]; pm++) { - if (aPersModel[pm]->hasModeData(0)) { - errVignette += aPersModel[pm]->vignette.mean_error; - vignetteCount++; - } - - if (aPersModel[pm]->hasModeData(1)) { - errBase += aPersModel[pm]->base.mean_error; - baseCount++; - } - - if (aPersModel[pm]->hasModeData(2)) { - errChrom += rtengine::max(aPersModel[pm]->chromRG.mean_error, aPersModel[pm]->chromG.mean_error, aPersModel[pm]->chromBG.mean_error); - chromCount++; - } - } - - // Only if we have enough frames, filter out errors - int filtered = 0; - - if (baseCount + chromCount + vignetteCount >= minFramesLeft) { - if (baseCount > 0) { - errBase /= (double)baseCount; - } - - if (chromCount > 0) { - errChrom /= (double)chromCount; - } - - if (vignetteCount > 0) { - errVignette /= (double)vignetteCount; - } - - // Now mark all the bad ones as bad, and hasModeData will return false; - for (int pm = 0; pm < MaxPersModelCount && aPersModel[pm]; pm++) { - if (aPersModel[pm]->hasModeData(0) && aPersModel[pm]->vignette.mean_error > maxAvgDevFac * errVignette) { - aPersModel[pm]->vignette.bad_error = true; - filtered++; - } - - if (aPersModel[pm]->hasModeData(1) && aPersModel[pm]->base.mean_error > maxAvgDevFac * errBase) { - aPersModel[pm]->base.bad_error = true; - filtered++; - } - - if (aPersModel[pm]->hasModeData(2) && - (aPersModel[pm]->chromRG.mean_error > maxAvgDevFac * errChrom || aPersModel[pm]->chromG.mean_error > maxAvgDevFac * errChrom - || aPersModel[pm]->chromBG.mean_error > maxAvgDevFac * errChrom)) { - aPersModel[pm]->chromRG.bad_error = aPersModel[pm]->chromG.bad_error = aPersModel[pm]->chromBG.bad_error = true; - filtered++; - } - } - - if (settings->verbose) { - printf("Filtered %.1f%% frames for maxAvgDevFac %g leaving %i\n", filtered*100./(baseCount+chromCount+vignetteCount), maxAvgDevFac, baseCount+chromCount+vignetteCount-filtered); - } - } - - return filtered; -} - - -// mode: 0=vignette, 1=distortion, 2=CA -void LCPProfile::calcParams(int mode, float focalLength, float focusDist, float aperture, LCPModelCommon *pCorr1, LCPModelCommon *pCorr2, LCPModelCommon *pCorr3) const -{ - float euler = exp(1.0); - - // find the frames with the least distance, focal length wise - LCPPersModel *pLow = nullptr, *pHigh = nullptr; - - float focalLengthLog = log(focalLength); //, apertureLog=aperture>0 ? log(aperture) : 0; - float focusDistLog = focusDist > 0 ? log(focusDist) + euler : 0; - - // Pass 1: determining best focal length, if possible different focusDistances (for the focDist is not given case) - for (int pm = 0; pm < persModelCount; pm++) { - float f = aPersModel[pm]->focLen; - - if (aPersModel[pm]->hasModeData(mode)) { - if (f <= focalLength && (pLow == nullptr || f > pLow->focLen || (focusDist == 0 && f == pLow->focLen && pLow->focDist > aPersModel[pm]->focDist))) { - pLow = aPersModel[pm]; - } - - if (f >= focalLength && (pHigh == nullptr || f < pHigh->focLen || (focusDist == 0 && f == pHigh->focLen && pHigh->focDist < aPersModel[pm]->focDist))) { - pHigh = aPersModel[pm]; - } - } - } - - if (!pLow) { - pLow = pHigh; - } else if (!pHigh) { - pHigh = pLow; - } else { - // Pass 2: We have some, so take the best aperture for vignette and best focus for CA and distortion - // there are usually several frame per focal length. In the end pLow will have both flen and apterure/focdis below the target, - // and vice versa pHigh - float bestFocLenLow = pLow->focLen, bestFocLenHigh = pHigh->focLen; - - for (int pm = 0; pm < persModelCount; pm++) { - float aper = aPersModel[pm]->aperture; // float aperLog=log(aper); - float focDist = aPersModel[pm]->focDist; - float focDistLog = log(focDist) + euler; - double meanErr; - if (aPersModel[pm]->hasModeData(mode)) { - double lowMeanErr, highMeanErr; - switch (mode) { - case 0: - meanErr = aPersModel[pm]->vignette.mean_error; - lowMeanErr = pLow->vignette.mean_error; - highMeanErr = pHigh->vignette.mean_error; - break; - case 1: - meanErr = aPersModel[pm]->base.mean_error; - lowMeanErr = pLow->base.mean_error; - highMeanErr = pHigh->base.mean_error; - break; - default: //case 2: - meanErr = aPersModel[pm]->chromG.mean_error; - lowMeanErr = pLow->chromG.mean_error; - highMeanErr = pHigh->chromG.mean_error; - break; - } - - if (aperture > 0 && mode != 2) { - if (aPersModel[pm]->focLen == bestFocLenLow && ( - (aper == aperture && lowMeanErr > meanErr) - || (aper >= aperture && aper < pLow->aperture && pLow->aperture > aperture) - || (aper <= aperture && (pLow->aperture > aperture || fabs(aperture - aper) < fabs(aperture - pLow->aperture))))) { - pLow = aPersModel[pm]; - } - - if (aPersModel[pm]->focLen == bestFocLenHigh && ( - (aper == aperture && highMeanErr > meanErr) - || (aper <= aperture && aper > pHigh->aperture && pHigh->aperture < aperture) - || (aper >= aperture && (pHigh->aperture < aperture || fabs(aperture - aper) < fabs(aperture - pHigh->aperture))))) { - pHigh = aPersModel[pm]; - } - } else if (focusDist > 0 && mode != 0) { - // by focus distance - if (aPersModel[pm]->focLen == bestFocLenLow && ( - (focDist == focusDist && lowMeanErr > meanErr) - || (focDist >= focusDist && focDist < pLow->focDist && pLow->focDist > focusDist) - || (focDist <= focusDist && (pLow->focDist > focusDist || fabs(focusDistLog - focDistLog) < fabs(focusDistLog - (log(pLow->focDist) + euler)))))) { - pLow = aPersModel[pm]; - } - - if (aPersModel[pm]->focLen == bestFocLenHigh && ( - (focDist == focusDist && highMeanErr > meanErr) - || (focDist <= focusDist && focDist > pHigh->focDist && pHigh->focDist < focusDist) - || (focDist >= focusDist && (pHigh->focDist < focusDist || fabs(focusDistLog - focDistLog) < fabs(focusDistLog - (log(pHigh->focDist) + euler)))))) { - pHigh = aPersModel[pm]; - } - } else { - // no focus distance available, just error - if (aPersModel[pm]->focLen == bestFocLenLow && lowMeanErr > meanErr) { - pLow = aPersModel[pm]; - } - - if (aPersModel[pm]->focLen == bestFocLenHigh && highMeanErr > meanErr) { - pHigh = aPersModel[pm]; - } - } - - } - } - } - - if (pLow != nullptr && pHigh != nullptr) { - // average out the factors, linear interpolation in logarithmic scale - float facLow = 0.5; - bool focLenOnSpot = false; // pretty often, since max/min are often as frames in LCP - - // There is as foclen range, take that as basis - if (pLow->focLen < pHigh->focLen) { - facLow = (log(pHigh->focLen) - focalLengthLog) / (log(pHigh->focLen) - log(pLow->focLen)); - } else { - focLenOnSpot = pLow->focLen == pHigh->focLen && pLow->focLen == focalLength; - } - - // and average the other factor if available - if (mode == 0 && pLow->aperture < aperture && pHigh->aperture > aperture) { - // Mix in aperture - float facAperLow = (pHigh->aperture - aperture) / (pHigh->aperture - pLow->aperture); - facLow = focLenOnSpot ? facAperLow : (0.5 * facLow + 0.5 * facAperLow); - } else if (mode != 0 && focusDist > 0 && pLow->focDist < focusDist && pHigh->focDist > focusDist) { - // focus distance for all else (if focus distance is given) - float facDistLow = (log(pHigh->focDist) + euler - focusDistLog) / (log(pHigh->focDist) - log(pLow->focDist)); - facLow = focLenOnSpot ? facDistLow : (0.8 * facLow + 0.2 * facDistLow); - } - - switch (mode) { - case 0: // vignette - pCorr1->merge(pLow->vignette, pHigh->vignette, facLow); - break; - - case 1: // distortion - pCorr1->merge(pLow->base, pHigh->base, facLow); - break; - - case 2: // CA - pCorr1->merge(pLow->chromRG, pHigh->chromRG, facLow); - pCorr2->merge(pLow->chromG, pHigh->chromG, facLow); - pCorr3->merge(pLow->chromBG, pHigh->chromBG, facLow); - break; - } - - if (settings->verbose) { - printf("LCP mode=%i, dist: %g found frames: Fno %g-%g; FocLen %g-%g; Dist %g-%g with weight %g\n", mode, focusDist, pLow->aperture, pHigh->aperture, pLow->focLen, pHigh->focLen, pLow->focDist, pHigh->focDist, facLow); - } - } else { - if (settings->verbose) { - printf("Error: LCP file contained no %s parameters\n", mode == 0 ? "vignette" : mode == 1 ? "distortion" : "CA" ); - } - } -} - -void LCPProfile::print() const -{ - printf("=== Profile %s\n", profileName.c_str()); - printf("Frames: %i, RAW: %i; Fisheye: %i; Sensorformat: %f\n", persModelCount, isRaw, isFisheye, sensorFormatFactor); - - for (int pm = 0; pm < persModelCount; pm++) { - aPersModel[pm]->print(); - } -} - -void XMLCALL LCPProfile::XmlStartHandler(void *pLCPProfile, const char *el, const char **attr) -{ - LCPProfile *pProf = static_cast(pLCPProfile); - bool parseAttr = false; - - if (*pProf->inInvalidTag) { - return; // We ignore everything in dirty tag till it's gone - } - - // clean up tagname - const char* src = strrchr(el, ':'); - - if (src == nullptr) { - src = const_cast(el); - } else { - src++; - } - - strcpy(pProf->lastTag, src); - - if (!strcmp("VignetteModelPiecewiseParam", src)) { - strcpy(pProf->inInvalidTag, src); - } - - if (!strcmp("CameraProfiles", src)) { - pProf->inCamProfiles = true; - } - - if (!strcmp("AlternateLensIDs", src)) { - pProf->inAlternateLensID = true; - } - - if (!strcmp("AlternateLensNames", src)) { - pProf->inAlternateLensNames = true; - } - - if (!pProf->inCamProfiles || pProf->inAlternateLensID || pProf->inAlternateLensNames) { - return; - } - - if (!strcmp("li", src)) { - pProf->pCurPersModel = new LCPPersModel(); - pProf->pCurCommon = &pProf->pCurPersModel->base; // iterated to next tags within persModel - return; - } - - if (!strcmp("PerspectiveModel", src)) { - pProf->firstLIDone = true; - pProf->inPerspect = true; - return; - } else if (!strcmp("FisheyeModel", src)) { - pProf->firstLIDone = true; - pProf->inPerspect = true; - pProf->isFisheye = true; // just misses third param, and different path, rest is the same - return; - } else if (!strcmp("Description", src)) { - parseAttr = true; - } - - // Move pointer to general section - if (pProf->inPerspect) { - if (!strcmp("ChromaticRedGreenModel", src)) { - pProf->pCurCommon = &pProf->pCurPersModel->chromRG; - parseAttr = true; - } else if (!strcmp("ChromaticGreenModel", src)) { - pProf->pCurCommon = &pProf->pCurPersModel->chromG; - parseAttr = true; - } else if (!strcmp("ChromaticBlueGreenModel", src)) { - pProf->pCurCommon = &pProf->pCurPersModel->chromBG; - parseAttr = true; - } else if (!strcmp("VignetteModel", src)) { - pProf->pCurCommon = &pProf->pCurPersModel->vignette; - parseAttr = true; - } - } - - // some profiles (espc. Pentax) have a different structure that is attributes based - // simulate tags by feeding them in - if (parseAttr && attr != nullptr) { - for (int i = 0; attr[i]; i += 2) { - const char* nameStart = strrchr(attr[i], ':'); - - if (nameStart == nullptr) { - nameStart = const_cast(attr[i]); - } else { - nameStart++; - } - - strncpy(pProf->lastTag, nameStart, 255); - - pProf->handle_text(attr[i+1]); - //XmlTextHandler(pLCPProfile, attr[i + 1], strlen(attr[i + 1])); - } - } -} - -void XMLCALL LCPProfile::XmlTextHandler(void *pLCPProfile, const XML_Char *s, int len) -{ - LCPProfile *pProf = static_cast(pLCPProfile); - - if (!pProf->inCamProfiles || pProf->inAlternateLensID || pProf->inAlternateLensNames || *pProf->inInvalidTag) { - return; - } - - for (int i = 0; i < len; ++i) { - pProf->textbuf << s[i]; - } -} - - -void LCPProfile::handle_text(std::string text) -{ - // Check if it contains non-whitespaces (there are several calls to this for one tag unfortunately) - bool onlyWhiteSpace = true; - for (size_t i = 0; i < text.size(); ++i) { - if (!isspace(text[i])) { - onlyWhiteSpace = false; - break; - } - } - - if (onlyWhiteSpace) { - return; - } - - LCPProfile *pProf = this; - - // convert to null terminated - char* tag = pProf->lastTag; - - const char* raw = text.c_str(); - - // Common data section - if (!pProf->firstLIDone) { - // Generic tags are the same for all - if (!strcmp("ProfileName", tag)) { - pProf->profileName = Glib::ustring(raw); - } else if (!strcmp("Model", tag)) { - pProf->camera = Glib::ustring(raw); - } else if (!strcmp("Lens", tag)) { - pProf->lens = Glib::ustring(raw); - } else if (!strcmp("CameraPrettyName", tag)) { - pProf->cameraPrettyName = Glib::ustring(raw); - } else if (!strcmp("LensPrettyName", tag)) { - pProf->lensPrettyName = Glib::ustring(raw); - } else if (!strcmp("CameraRawProfile", tag)) { - pProf->isRaw = !strcmp("True", raw); - } - } - - // --- Now all floating points. Must replace local dot characters - // WARNING: called by different threads, that may run on different local settings, - // so don't use system params - if (atof("1,2345") == 1.2345) { - for (size_t i = 0; i < text.size(); ++i) { - if (text[i] == '.') { - text[i] = ','; - } - } - raw = text.c_str(); - } - - if (!pProf->firstLIDone) { - if (!strcmp("SensorFormatFactor", tag)) { - pProf->sensorFormatFactor = atof(raw); - } - } - - // Perspective model base data - if (!strcmp("FocalLength", tag)) { - pProf->pCurPersModel->focLen = atof(raw); - } else if (!strcmp("FocusDistance", tag)) { - double focDist = atof(raw); - pProf->pCurPersModel->focDist = focDist < 10000 ? focDist : 10000; - } else if (!strcmp("ApertureValue", tag)) { - pProf->pCurPersModel->aperture = atof(raw); - } - - // Section depended - if (!strcmp("FocalLengthX", tag)) { - pProf->pCurCommon->foc_len_x = atof(raw); - } else if (!strcmp("FocalLengthY", tag)) { - pProf->pCurCommon->foc_len_y = atof(raw); - } else if (!strcmp("ImageXCenter", tag)) { - pProf->pCurCommon->img_center_x = atof(raw); - } else if (!strcmp("ImageYCenter", tag)) { - pProf->pCurCommon->img_center_y = atof(raw); - } else if (!strcmp("ScaleFactor", tag)) { - pProf->pCurCommon->scale_factor = atof(raw); - } else if (!strcmp("ResidualMeanError", tag)) { - pProf->pCurCommon->mean_error = atof(raw); - } else if (!strcmp("RadialDistortParam1", tag) || !strcmp("VignetteModelParam1", tag)) { - pProf->pCurCommon->param[0] = atof(raw); - } else if (!strcmp("RadialDistortParam2", tag) || !strcmp("VignetteModelParam2", tag)) { - pProf->pCurCommon->param[1] = atof(raw); - } else if (!strcmp("RadialDistortParam3", tag) || !strcmp("VignetteModelParam3", tag)) { - pProf->pCurCommon->param[2] = atof(raw); - } else if (!strcmp("RadialDistortParam4", tag) || !strcmp("TangentialDistortParam1", tag)) { - pProf->pCurCommon->param[3] = atof(raw); - } else if (!strcmp("RadialDistortParam5", tag) || !strcmp("TangentialDistortParam2", tag)) { - pProf->pCurCommon->param[4] = atof(raw); - } -} - -void XMLCALL LCPProfile::XmlEndHandler(void *pLCPProfile, const char *el) -{ - LCPProfile *pProf = static_cast(pLCPProfile); - - pProf->handle_text(pProf->textbuf.str()); - pProf->textbuf.str(""); - - // We ignore everything in dirty tag till it's gone - if (*pProf->inInvalidTag) { - if (strstr(el, pProf->inInvalidTag)) { - *pProf->inInvalidTag = 0; - } - - return; - } - - if (strstr(el, ":CameraProfiles")) { - pProf->inCamProfiles = false; - } - - if (strstr(el, ":AlternateLensIDs")) { - pProf->inAlternateLensID = false; - } - - if (strstr(el, ":AlternateLensNames")) { - pProf->inAlternateLensNames = false; - } - - if (!pProf->inCamProfiles || pProf->inAlternateLensID || pProf->inAlternateLensNames) { - return; - } - - if (strstr(el, ":PerspectiveModel") || strstr(el, ":FisheyeModel")) { - pProf->inPerspect = false; - } else if (strstr(el, ":li")) { - pProf->aPersModel[pProf->persModelCount] = pProf->pCurPersModel; - pProf->pCurPersModel = nullptr; - pProf->persModelCount++; - } -} - -// Generates as singleton -LCPStore* LCPStore::getInstance() -{ - static LCPStore instance_; - return &instance_; -} - - -LCPStore::~LCPStore() -{ - for (auto &p : profileCache) { - delete p.second; - } -} - - -LCPProfile* LCPStore::getProfile (Glib::ustring filename) -{ - if (filename.length() == 0 || !isValidLCPFileName(filename)) { - return nullptr; - } - - MyMutex::MyLock lock(mtx); - - std::map::iterator r = profileCache.find (filename); - - if (r != profileCache.end()) { - return r->second; - } - - // Add profile (if exists) - profileCache[filename] = new LCPProfile(filename); - if (settings->verbose) { - profileCache[filename]->print(); - } - return profileCache[filename]; -} - -bool LCPStore::isValidLCPFileName(Glib::ustring filename) const -{ - if (!Glib::file_test (filename, Glib::FILE_TEST_EXISTS) || Glib::file_test (filename, Glib::FILE_TEST_IS_DIR)) { - return false; - } - - size_t pos = filename.find_last_of ('.'); - return pos > 0 && !filename.casefold().compare (pos, 4, ".lcp"); -} - -Glib::ustring LCPStore::getDefaultCommonDirectory() const -{ - Glib::ustring dir; - -#ifdef WIN32 - WCHAR pathW[MAX_PATH] = {0}; - - if (SHGetSpecialFolderPathW(NULL, pathW, CSIDL_COMMON_APPDATA, false)) { - char pathA[MAX_PATH]; - WideCharToMultiByte(CP_UTF8, 0, pathW, -1, pathA, MAX_PATH, 0, 0); - Glib::ustring fullDir = Glib::ustring(pathA) + Glib::ustring("\\Adobe\\CameraRaw\\LensProfiles\\1.0"); - - if (Glib::file_test (fullDir, Glib::FILE_TEST_IS_DIR)) { - dir = fullDir; - } - } - -#endif - - // TODO: Add Mac paths here - - return dir; -} diff --git a/rtengine/lcp.h b/rtengine/lcp.h index f7164117f..b50fd335e 100644 --- a/rtengine/lcp.h +++ b/rtengine/lcp.h @@ -21,27 +21,45 @@ #include #include +#include #include #include #include #include +#include "cache.h" #include "imagefloat.h" #include "opthelper.h" namespace rtengine { +enum class LCPCorrectionMode { + VIGNETTE, + DISTORTION, + CA +}; + // Perspective model common data, also used for Vignette and Fisheye class LCPModelCommon final { 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, int fullHeight, float focalLength, float focalLength35mm, float sensorFormatFactor, bool swapXY, bool mirrorX, bool mirrorY); + void prepareParams( + int fullWidth, + int fullHeight, + float focalLength, + float focalLength35mm, + float sensorFormatFactor, + bool swapXY, + bool mirrorX, + bool mirrorY + ); //private: using Param = std::array; @@ -66,97 +84,125 @@ public: VignParam vign_param; }; -class LCPPersModel -{ -public: - float focLen, focDist, aperture; // this is what it refers to - - LCPModelCommon base; // base perspective correction - LCPModelCommon chromRG, chromG, chromBG; // red/green, green, blue/green (may be empty) - LCPModelCommon vignette; // vignette (may be empty) - - LCPPersModel(); - bool hasModeData(int mode) const; - void print() const; -}; - - class LCPProfile { - // Temporary data for parsing - bool inCamProfiles, firstLIDone, inPerspect, inAlternateLensID, inAlternateLensNames; - char lastTag[256], inInvalidTag[256]; - LCPPersModel* pCurPersModel; - LCPModelCommon* pCurCommon; - - static void XMLCALL XmlStartHandler(void *pLCPProfile, const char *el, const char **attr); - static void XMLCALL XmlTextHandler (void *pLCPProfile, const XML_Char *s, int len); - static void XMLCALL XmlEndHandler (void *pLCPProfile, const char *el); - - int filterBadFrames(double maxAvgDevFac, int minFramesLeft); - - void handle_text(std::string text); - std::ostringstream textbuf; - public: + explicit LCPProfile(const Glib::ustring& fname); + ~LCPProfile(); + + void calcParams( + LCPCorrectionMode mode, + float focalLength, + float focusDist, + float aperture, + LCPModelCommon* pCorr1, + LCPModelCommon* pCorr2, + LCPModelCommon *pCorr3 + ) const; // Interpolates between the persModels frames + + void print() const; + +//private: // Common data - Glib::ustring profileName, lensPrettyName, cameraPrettyName, lens, camera; // lens/camera(=model) can be auto-matched with DNG - bool isRaw, isFisheye; + Glib::ustring profileName; + Glib::ustring lensPrettyName; + Glib::ustring cameraPrettyName; + Glib::ustring lens; + Glib::ustring camera; // lens/camera(=model) can be auto-matched with DNG + bool isRaw; + bool isFisheye; float sensorFormatFactor; int persModelCount; +private: + class LCPPersModel; + + int filterBadFrames(LCPCorrectionMode mode, double maxAvgDevFac, int minFramesLeft); + + void handle_text(const std::string& text); + + static void XMLCALL XmlStartHandler(void* pLCPProfile, const char* el, const char** attr); + static void XMLCALL XmlTextHandler(void* pLCPProfile, const XML_Char* s, int len); + static void XMLCALL XmlEndHandler(void* pLCPProfile, const char* el); + + // Temporary data for parsing + bool inCamProfiles; + bool firstLIDone; + bool inPerspect; + bool inAlternateLensID; + bool inAlternateLensNames; + char lastTag[256]; + char inInvalidTag[256]; + LCPPersModel* pCurPersModel; + LCPModelCommon* pCurCommon; + + std::ostringstream textbuf; + // The correction frames - static const int MaxPersModelCount = 3000; + static constexpr int MaxPersModelCount = 3000; LCPPersModel* aPersModel[MaxPersModelCount]; // Do NOT use std::list or something, it's buggy in GCC! - - explicit LCPProfile(const Glib::ustring &fname); - ~LCPProfile(); - - void calcParams(int mode, float focalLength, float focusDist, float aperture, LCPModelCommon *pCorr1, LCPModelCommon *pCorr2, LCPModelCommon *pCorr3) const; // Interpolates between the persModels frames - - void print() const; }; class LCPStore { - MyMutex mtx; +public: + static LCPStore* getInstance(); + + bool isValidLCPFileName(const Glib::ustring& filename) const; + std::shared_ptr getProfile(const Glib::ustring& filename) const; + Glib::ustring getDefaultCommonDirectory() const; + +private: + LCPStore(unsigned int _cache_size = 32); // Maps file name to profile as cache - std::map profileCache; - -public: - ~LCPStore(); - Glib::ustring getDefaultCommonDirectory() const; - bool isValidLCPFileName(Glib::ustring filename) const; - LCPProfile* getProfile(Glib::ustring filename); - - static LCPStore* getInstance(); + mutable Cache> cache; }; -#define lcpStore LCPStore::getInstance() +class LensCorrection { +public: + virtual ~LensCorrection() {} + virtual void correctDistortion(double &x, double &y, int cx, int cy, double scale) const = 0; + virtual bool isCACorrectionAvailable() const = 0; + virtual void correctCA(double &x, double &y, int cx, int cy, int channel) const = 0; + virtual void processVignetteLine(int width, int y, float *line) const = 0; + virtual void processVignetteLine3Channels(int width, int y, float *line) const = 0; +}; // Once precalculated class to correct a point -class LCPMapper +class LCPMapper: public LensCorrection { +public: + // Precalculates the mapper + LCPMapper( + const std::shared_ptr& pProf, + float focalLength, + float focalLength35mm, + float focusDist, + float aperture, + bool vignette, + bool useCADistP, + int fullWidth, + int fullHeight, + const CoarseTransformParams& coarse, + int rawRotationDeg + ); + + void correctDistortion(double &x, double &y, int cx, int cy, double scale) const; // MUST be the first stage + bool isCACorrectionAvailable() const; + void correctCA(double& x, double& y, int cx, int cy, int channel) const; + void processVignetteLine(int width, int y, float* line) const; + void processVignetteLine3Channels(int width, int y, float* line) const; + +private: + bool enableCA; // is the mapper capable if CA correction? bool useCADist; // should the distortion in the CA info be used? bool swapXY; LCPModelCommon mc; LCPModelCommon chrom[3]; // in order RedGreen/Green/BlueGreen bool isFisheye; - -public: - bool enableCA; // is the mapper capable if CA correction? - - // precalculates the mapper. - LCPMapper(LCPProfile* pProf, float focalLength, float focalLength35mm, float focusDist, float aperture, bool vignette, bool useCADistP, int fullWidth, int fullHeight, - const CoarseTransformParams& coarse, int rawRotationDeg); - - void correctDistortion(double& x, double& y, double scale) const; // MUST be the first stage - void correctCA(double& x, double& y, int channel) const; - void processVignetteLine(int width, int y, float *line) const; - void processVignetteLine3Channels(int width, int y, float *line) const; }; } diff --git a/rtengine/loadinitial.cc b/rtengine/loadinitial.cc index c29d60621..6192ca6db 100644 --- a/rtengine/loadinitial.cc +++ b/rtengine/loadinitial.cc @@ -36,11 +36,7 @@ InitialImage* InitialImage::load (const Glib::ustring& fname, bool isRaw, int* e isrc->setProgressListener (pl); - if(isRaw && pl == nullptr) { - *errorCode = isrc->load (fname, true); - } else { - *errorCode = isrc->load (fname); - } + *errorCode = isrc->load (fname); if (*errorCode) { delete isrc; diff --git a/rtengine/myfile.cc b/rtengine/myfile.cc index 903fd8354..920421188 100644 --- a/rtengine/myfile.cc +++ b/rtengine/myfile.cc @@ -33,6 +33,11 @@ #define PROT_READ 1 #define MAP_FAILED (void *)-1 +#ifdef __GNUC__ // silence warning +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + void* mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset) { HANDLE handle = CreateFileMapping((HANDLE)_get_osfhandle(fd), NULL, PAGE_WRITECOPY, 0, 0, NULL); @@ -51,6 +56,9 @@ int munmap(void *start, size_t length) UnmapViewOfFile(start); return 0; } +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif #else // WIN32 diff --git a/rtengine/opthelper.h b/rtengine/opthelper.h index 5e9b97931..d6af9a745 100644 --- a/rtengine/opthelper.h +++ b/rtengine/opthelper.h @@ -22,6 +22,8 @@ #ifndef OPTHELPER_H #define OPTHELPER_H + #define pow_F(a,b) (xexpf(b*xlogf(a))) + #ifdef __SSE2__ #include "sleefsseavx.c" #ifdef __GNUC__ diff --git a/rtengine/previewimage.cc b/rtengine/previewimage.cc index aba43ace5..1bd72a354 100644 --- a/rtengine/previewimage.cc +++ b/rtengine/previewimage.cc @@ -59,7 +59,8 @@ PreviewImage::PreviewImage (const Glib::ustring &fname, const Glib::ustring &ext } } else { rtengine::RawMetaDataLocation ri; - tpp = rtengine::Thumbnail::loadQuickFromRaw (fname, ri, width, height, 1, true, true); + eSensorType sensorType = rtengine::ST_NONE; + tpp = rtengine::Thumbnail::loadQuickFromRaw (fname, ri, sensorType, width, height, 1, true, true); if (tpp) { data = tpp->getImage8Data(); @@ -96,7 +97,7 @@ PreviewImage::PreviewImage (const Glib::ustring &fname, const Glib::ustring &ext if ((mode == PIM_EmbeddedOrRaw && !tpp) || mode == PIM_ForceRaw) { RawImageSource rawImage; - int error = rawImage.load(fname, true); + int error = rawImage.load(fname); if (!error) { const unsigned char *data = nullptr; @@ -114,7 +115,7 @@ PreviewImage::PreviewImage (const Glib::ustring &fname, const Glib::ustring &ext rawImage.preprocess(params.raw, params.lensProf, params.coarse); rawImage.demosaic(params.raw); Imagefloat image(fw, fh); - rawImage.getImage (wb, TR_NONE, &image, pp, params.toneCurve, params.icm, params.raw); + rawImage.getImage (wb, TR_NONE, &image, pp, params.toneCurve, params.raw); rtengine::Image8 output(fw, fh); rawImage.convertColorSpace(&image, params.icm, wb); #pragma omp parallel for schedule(dynamic, 10) diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 8f1e3dc76..53f33d4e3 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -511,6 +511,14 @@ enum ProcEvent { EvCATgreensc = 481, EvCATybscen = 482, EvCATAutoyb = 483, + // profiled lens correction new events + EvLensCorrMode = 484, + EvLensCorrLensfunCamera = 485, + EvLensCorrLensfunLens = 486, + // Fattal tone mapping + EvTMFattalEnabled = 487, + EvTMFattalThreshold = 488, + EvTMFattalAmount = 489, NUMOFEVENTS diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 953715331..71ce3a1e3 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -18,7 +18,6 @@ */ #include #include "procparams.h" -#include "rt_math.h" #include "curves.h" #include "../rtgui/multilangmgr.h" #include "../rtgui/version.h" @@ -26,6 +25,7 @@ #include "../rtgui/paramsedited.h" #include "../rtgui/options.h" #include + #define APPVERSION RTVERSION using namespace std; @@ -52,6 +52,7 @@ const int br = (int) options.rtSettings.bot_right; const int tl = (int) options.rtSettings.top_left; const int bl = (int) options.rtSettings.bot_left; +const char *LensProfParams::methodstring[static_cast(LensProfParams::LcMode::LCP) + 1u] = {"none", "lfauto", "lfmanual", "lcp"}; const char *RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::numMethods] = {"amaze", "igv", "lmmse", "eahd", "hphd", "vng4", "dcb", "ahd", "fast", "mono", "none", "pixelshift" }; const char *RAWParams::XTransSensor::methodstring[RAWParams::XTransSensor::numMethods] = {"3-pass (best)", "1-pass (medium)", "fast", "mono", "none" }; @@ -560,7 +561,7 @@ void ColorToningParams::slidersToCurve (std::vector &colorCurve, std::ve opacityCurve.at (8) = 0.35; } -void ColorToningParams::getCurves (ColorGradientCurve &colorCurveLUT, OpacityCurve &opacityCurveLUT, const double xyz_rgb[3][3], const double rgb_xyz[3][3], bool &opautili) const +void ColorToningParams::getCurves (ColorGradientCurve &colorCurveLUT, OpacityCurve &opacityCurveLUT, const double xyz_rgb[3][3], bool &opautili) const { float satur = 0.8f; float lumin = 0.5f; //middle of luminance for optimization of gamut - no real importance...as we work in XYZ and gamut control @@ -586,13 +587,13 @@ void ColorToningParams::getCurves (ColorGradientCurve &colorCurveLUT, OpacityCur satur = 0.9f; } - colorCurveLUT.SetXYZ (cCurve, xyz_rgb, rgb_xyz, satur, lumin); + colorCurveLUT.SetXYZ (cCurve, xyz_rgb, satur, lumin); opacityCurveLUT.Set (oCurve, opautili); } else if (method == "Splitlr" || method == "Splitco") { - colorCurveLUT.SetXYZ (cCurve, xyz_rgb, rgb_xyz, satur, lumin); + colorCurveLUT.SetXYZ (cCurve, xyz_rgb, satur, lumin); opacityCurveLUT.Set (oCurve, opautili); } else if (method.substr (0, 3) == "RGB") { - colorCurveLUT.SetRGB (cCurve, xyz_rgb, rgb_xyz); + colorCurveLUT.SetRGB (cCurve); opacityCurveLUT.Set (oCurve, opautili); } } @@ -922,9 +923,13 @@ void ToneCurveParams::setDefaults() void LensProfParams::setDefaults() { + lcMode = LcMode::NONE; lcpFile = ""; useDist = useVign = true; useCA = false; + lfCameraMake = ""; + lfCameraModel = ""; + lfLens = ""; } void CoarseTransformParams::setDefaults() @@ -1246,6 +1251,8 @@ void ProcParams::setDefaults () epd.scale = 1.0; epd.reweightingIterates = 0; + fattal.setDefaults(); + sh.enabled = false; sh.hq = false; sh.highlights = 0; @@ -2447,6 +2454,19 @@ int ProcParams::save (const Glib::ustring &fname, const Glib::ustring &fname2, b keyFile.set_integer ("EPD", "ReweightingIterates", epd.reweightingIterates); } +// save fattal + if (!pedited || pedited->fattal.enabled) { + keyFile.set_boolean ("FattalToneMapping", "Enabled", fattal.enabled); + } + + if (!pedited || pedited->fattal.threshold) { + keyFile.set_integer ("FattalToneMapping", "Threshold", fattal.threshold); + } + + if (!pedited || pedited->fattal.amount) { + keyFile.set_integer ("FattalToneMapping", "Amount", fattal.amount); + } + /* // save lumaDenoise if (!pedited || pedited->lumaDenoise.enabled) keyFile.set_boolean ("Luminance Denoising", "Enabled", lumaDenoise.enabled); @@ -2559,6 +2579,10 @@ int ProcParams::save (const Glib::ustring &fname, const Glib::ustring &fname2, b } // lens profile + if (!pedited || pedited->lensProf.lcMode) { + keyFile.set_string ("LensProfile", "LcMode", lensProf.getMethodString (lensProf.lcMode)); + } + if (!pedited || pedited->lensProf.lcpFile) { keyFile.set_string ("LensProfile", "LCPFile", relativePathIfInside (fname, fnameAbsolute, lensProf.lcpFile)); } @@ -2575,6 +2599,16 @@ int ProcParams::save (const Glib::ustring &fname, const Glib::ustring &fname2, b keyFile.set_boolean ("LensProfile", "UseCA", lensProf.useCA); } + if (!pedited || pedited->lensProf.lfCameraMake) { + keyFile.set_string("LensProfile", "LFCameraMake", lensProf.lfCameraMake); + } + if (!pedited || pedited->lensProf.lfCameraModel) { + keyFile.set_string("LensProfile", "LFCameraModel", lensProf.lfCameraModel); + } + if (!pedited || pedited->lensProf.lfLens) { + keyFile.set_string("LensProfile", "LFLens", lensProf.lfLens); + } + // save perspective correction if (!pedited || pedited->perspective.horizontal) { keyFile.set_double ("Perspective", "Horizontal", perspective.horizontal); @@ -5600,6 +5634,33 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) } } +//Load FattalToneMapping + if (keyFile.has_group ("FattalToneMapping")) { + if (keyFile.has_key ("FattalToneMapping", "Enabled")) { + fattal.enabled = keyFile.get_boolean ("FattalToneMapping", "Enabled"); + + if (pedited) { + pedited->fattal.enabled = true; + } + } + + if (keyFile.has_key ("FattalToneMapping", "Threshold")) { + fattal.threshold = keyFile.get_double ("FattalToneMapping", "Threshold"); + + if (pedited) { + pedited->fattal.threshold = true; + } + } + + if (keyFile.has_key ("FattalToneMapping", "Amount")) { + fattal.amount = keyFile.get_double ("FattalToneMapping", "Amount"); + + if (pedited) { + pedited->fattal.amount = true; + } + } + } + // load lumaDenoise /*if (keyFile.has_group ("Luminance Denoising")) { if (keyFile.has_key ("Luminance Denoising", "Enabled")) { lumaDenoise.enabled = keyFile.get_boolean ("Luminance Denoising", "Enabled"); if (pedited) pedited->lumaDenoise.enabled = true; } @@ -5832,12 +5893,24 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) // lens profile if (keyFile.has_group ("LensProfile")) { + if (keyFile.has_key ("LensProfile", "LcMode")) { + lensProf.lcMode = lensProf.getMethodNumber (keyFile.get_string ("LensProfile", "LcMode")); + + if (pedited) { + pedited->lensProf.lcMode = true; + } + } + if (keyFile.has_key ("LensProfile", "LCPFile")) { lensProf.lcpFile = expandRelativePath (fname, "", keyFile.get_string ("LensProfile", "LCPFile")); if (pedited) { pedited->lensProf.lcpFile = true; } + + if(ppVersion < 327 && !lensProf.lcpFile.empty()) { + lensProf.lcMode = LensProfParams::LcMode::LCP; + } } if (keyFile.has_key ("LensProfile", "UseDistortion")) { @@ -5863,6 +5936,27 @@ int ProcParams::load (const Glib::ustring &fname, ParamsEdited* pedited) pedited->lensProf.useCA = true; } } + + if (keyFile.has_key("LensProfile", "LFCameraMake")) { + lensProf.lfCameraMake = keyFile.get_string("LensProfile", "LFCameraMake"); + if (pedited) { + pedited->lensProf.lfCameraMake = true; + } + } + + if (keyFile.has_key("LensProfile", "LFCameraModel")) { + lensProf.lfCameraModel = keyFile.get_string("LensProfile", "LFCameraModel"); + if (pedited) { + pedited->lensProf.lfCameraModel = true; + } + } + + if (keyFile.has_key("LensProfile", "LFLens")) { + lensProf.lfLens = keyFile.get_string("LensProfile", "LFLens"); + if (pedited) { + pedited->lensProf.lfLens = true; + } + } } // load perspective correction @@ -8455,6 +8549,9 @@ bool ProcParams::operator== (const ProcParams& other) && epd.edgeStopping == other.epd.edgeStopping && epd.scale == other.epd.scale && epd.reweightingIterates == other.epd.reweightingIterates + && fattal.enabled == other.fattal.enabled + && fattal.threshold == other.fattal.threshold + && fattal.amount == other.fattal.amount && defringe.enabled == other.defringe.enabled && defringe.radius == other.defringe.radius && defringe.threshold == other.defringe.threshold @@ -8489,10 +8586,14 @@ bool ProcParams::operator== (const ProcParams& other) && rotate.degree == other.rotate.degree && commonTrans.autofill == other.commonTrans.autofill && distortion.amount == other.distortion.amount + && lensProf.lcMode == other.lensProf.lcMode && lensProf.lcpFile == other.lensProf.lcpFile && lensProf.useDist == other.lensProf.useDist && lensProf.useVign == other.lensProf.useVign && lensProf.useCA == other.lensProf.useCA + && lensProf.lfCameraMake == other.lensProf.lfCameraMake + && lensProf.lfCameraModel == other.lensProf.lfCameraModel + && lensProf.lfLens == other.lensProf.lfLens && perspective.horizontal == other.perspective.horizontal && perspective.vertical == other.perspective.vertical && gradient.enabled == other.gradient.enabled @@ -8834,7 +8935,7 @@ void PartialProfile::clearGeneral () } } -const void PartialProfile::applyTo (ProcParams *destParams) const +void PartialProfile::applyTo (ProcParams *destParams) const { if (destParams && pparams && pedited) { pedited->combine (*destParams, *pparams, true); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 7d9c42b40..a095ca16b 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -435,7 +435,7 @@ public: /// @brief Specifically transform the sliders values to their curve equivalences void slidersToCurve (std::vector &colorCurve, std::vector &opacityCurve) const; /// @brief Fill the ColorGradientCurve and OpacityCurve LUTf from the control points curve or sliders value - void getCurves (ColorGradientCurve &colorCurveLUT, OpacityCurve &opacityCurveLUT, const double xyz_rgb[3][3], const double rgb_xyz[3][3], bool &opautili) const; + void getCurves (ColorGradientCurve &colorCurveLUT, OpacityCurve &opacityCurveLUT, const double xyz_rgb[3][3], bool &opautili) const; static void getDefaultColorCurve (std::vector &curve); static void getDefaultOpacityCurve (std::vector &curve); @@ -738,6 +738,27 @@ public: int reweightingIterates; }; + +// Fattal02 Tone-Mapping parameters +class FattalToneMappingParams { +public: + bool enabled; + int threshold; + int amount; + + FattalToneMappingParams() + { + setDefaults(); + } + + void setDefaults() + { + enabled = false; + threshold = 0; + amount = 1; + } +}; + /** * Parameters of the shadow/highlight enhancement */ @@ -829,16 +850,64 @@ class LensProfParams { public: + enum class LcMode { + NONE, // No lens correction + LENSFUNAUTOMATCH, // Lens correction using auto matched lensfun database entry + LENSFUNMANUAL, // Lens correction using manually selected lensfun database entry + LCP // Lens correction using lcp file + }; + + static const char *methodstring[static_cast(LcMode::LCP) + 1u]; + LcMode lcMode; Glib::ustring lcpFile; bool useDist, useVign, useCA; + Glib::ustring lfCameraMake; + Glib::ustring lfCameraModel; + Glib::ustring lfLens; LensProfParams() { setDefaults(); } void setDefaults(); + + bool useLensfun() const + { + return lcMode == LcMode::LENSFUNAUTOMATCH || lcMode == LcMode::LENSFUNMANUAL; + } + + bool lfAutoMatch() const + { + return lcMode == LcMode::LENSFUNAUTOMATCH; + } + + bool useLcp() const + { + return lcMode == LcMode::LCP && lcpFile.length() > 0; + } + + bool lfManual() const + { + return lcMode == LcMode::LENSFUNMANUAL; + } + + Glib::ustring getMethodString(LcMode mode) const + { + return methodstring[static_cast(mode)]; + } + + LcMode getMethodNumber(const Glib::ustring &mode) const + { + for(size_t i = 0; i <= static_cast(LcMode::LCP); ++i) { + if(methodstring[i] == mode) { + return static_cast(i); + } + } + return LcMode::NONE; + } }; + /** * Parameters of the perspective correction */ @@ -1385,6 +1454,7 @@ public: ImpulseDenoiseParams impulseDenoise; ///< Impulse denoising parameters DirPyrDenoiseParams dirpyrDenoise; ///< Directional Pyramid denoising parameters EPDParams epd; ///< Edge Preserving Decomposition parameters + FattalToneMappingParams fattal; ///< Fattal02 tone mapping SHParams sh; ///< Shadow/highlight enhancement parameters CropParams crop; ///< Crop parameters CoarseTransformParams coarse; ///< Coarse transformation (90, 180, 270 deg rotation, h/v flipping) parameters @@ -1495,7 +1565,7 @@ public: void clearGeneral (); int load (const Glib::ustring &fName); void set (bool v); - const void applyTo (ProcParams *destParams) const ; + void applyTo (ProcParams *destParams) const ; }; /** diff --git a/rtengine/profilestore.cc b/rtengine/profilestore.cc index c713d6b5c..4d06b6f6b 100644 --- a/rtengine/profilestore.cc +++ b/rtengine/profilestore.cc @@ -498,7 +498,7 @@ void ProfileStore::dumpFolderList() printf ("\n"); } -PartialProfile *ProfileStore::loadDynamicProfile (const ImageMetaData *im) +PartialProfile *ProfileStore::loadDynamicProfile (const FramesMetaData *im) { if (storeState == STORESTATE_NOTINITIALIZED) { parseProfilesOnce(); diff --git a/rtengine/profilestore.h b/rtengine/profilestore.h index 372dbfc3b..4949517da 100644 --- a/rtengine/profilestore.h +++ b/rtengine/profilestore.h @@ -195,7 +195,7 @@ public: void addListener (ProfileStoreListener *listener); void removeListener (ProfileStoreListener *listener); - rtengine::procparams::PartialProfile* loadDynamicProfile (const rtengine::ImageMetaData *im); + rtengine::procparams::PartialProfile* loadDynamicProfile (const rtengine::FramesMetaData *im); void dumpFolderList(); }; diff --git a/rtengine/rawimage.cc b/rtengine/rawimage.cc index f36e798d9..de392623d 100644 --- a/rtengine/rawimage.cc +++ b/rtengine/rawimage.cc @@ -112,7 +112,10 @@ void RawImage::get_colorsCoeff( float *pre_mul_, float *scale_mul_, float *cblac } } - if (data && (this->get_cam_mul(0) == -1 || forceAutoWB)) { + if (this->get_cam_mul(0) == -1 || forceAutoWB) { + if(!data) { // this happens only for thumbnail creation when get_cam_mul(0) == -1 + compress_image(0, false); + } memset(dsum, 0, sizeof dsum); if (this->isBayer()) { @@ -673,7 +676,7 @@ int RawImage::loadRaw (bool loadData, unsigned int imageNum, bool closeFile, Pro return 0; } -float** RawImage::compress_image(int frameNum) +float** RawImage::compress_image(int frameNum, bool freeImage) { if( !image ) { return nullptr; @@ -757,8 +760,10 @@ float** RawImage::compress_image(int frameNum) } } - free(image); // we don't need this anymore - image = nullptr; + if(freeImage) { + free(image); // we don't need this anymore + image = nullptr; + } return data; } diff --git a/rtengine/rawimage.h b/rtengine/rawimage.h index 62752b59c..95e7aea8d 100644 --- a/rtengine/rawimage.h +++ b/rtengine/rawimage.h @@ -20,9 +20,11 @@ #define __RAWIMAGE_H #include +#include +#include #include "dcraw.h" -#include "imageio.h" +#include "imageformat.h" #include "noncopyable.h" namespace rtengine @@ -119,7 +121,7 @@ public: { return image; } - float** compress_image(int frameNum); // revert to compressed pixels format and release image data + float** compress_image(int frameNum, bool freeImage = true); // revert to compressed pixels format and release image data float** data; // holds pixel values, data[i][j] corresponds to the ith row and jth column unsigned prefilters; // original filters saved ( used for 4 color processing ) unsigned int getFrameCount() const { return is_raw; } @@ -233,7 +235,13 @@ public: } float get_pre_mul(int c )const { - return pre_mul[c]; + if(std::isfinite(pre_mul[c])) { + return pre_mul[c]; + } else { + std::cout << "Failure decoding '" << filename << "', please file a bug report including the raw file and the line below:" << std::endl; + std::cout << "rawimage.h get_pre_mul() : pre_mul[" << c << "] value " << pre_mul[c] << " automatically replaced by value 1.0" << std::endl; + return 1.f; + } } float get_rgb_cam( int r, int c) const { diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 148d17ee9..5eb7aa7b9 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -33,6 +33,7 @@ #include "dcp.h" #include "rt_math.h" #include "improcfun.h" +#include "rtlensfun.h" #ifdef _OPENMP #include #endif @@ -86,7 +87,7 @@ void transLineStandard (const float* const red, const float* const green, const 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 imwidth, 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 @@ -622,7 +623,7 @@ 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 ColorManagementParams &cmp, 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); @@ -823,7 +824,7 @@ void RawImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* ima 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, imwidth, 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); } @@ -909,11 +910,11 @@ void RawImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* ima } } -DCPProfile *RawImageSource::getDCP(const ColorManagementParams &cmp, ColorTemp &wb, DCPProfile::ApplyState &as) +DCPProfile *RawImageSource::getDCP(const ColorManagementParams &cmp, DCPProfile::ApplyState &as) { DCPProfile *dcpProf = nullptr; cmsHPROFILE dummy; - findInputProfile(cmp.input, nullptr, (static_cast(getMetaData()))->getCamera(), &dcpProf, dummy); + findInputProfile(cmp.input, nullptr, (static_cast(getMetaData()))->getCamera(), &dcpProf, dummy); if (dcpProf == nullptr) { if (settings->verbose) { @@ -929,7 +930,7 @@ DCPProfile *RawImageSource::getDCP(const ColorManagementParams &cmp, ColorTemp & 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()); } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -1517,7 +1518,7 @@ void RawImageSource::vflip (Imagefloat* image) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -int RawImageSource::load (const Glib::ustring &fname, int imageNum, bool batch) +int RawImageSource::load (const Glib::ustring &fname) { MyTime t1, t2; @@ -1698,12 +1699,10 @@ int RawImageSource::load (const Glib::ustring &fname, int imageNum, bool batch) } - //Load complete Exif informations - RawMetaDataLocation rml; - rml.exifBase = ri->get_exifBase(); - rml.ciffBase = ri->get_ciffBase(); - rml.ciffLength = ri->get_ciffLen(); - idata = new ImageData (fname, &rml); + // Load complete Exif informations + 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); @@ -1855,11 +1854,19 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le // Correct vignetting of lens profile if (!hasFlatField && lensProf.useVign) { - LCPProfile *pLCPProf = lcpStore->getProfile(lensProf.lcpFile); + std::unique_ptr pmap; + if (lensProf.useLensfun()) { + pmap = LFDatabase::findModifier(lensProf, idata, W, H, coarse, -1); + } else { + const std::shared_ptr pLCPProf = LCPStore::getInstance()->getProfile(lensProf.lcpFile); - if (pLCPProf) { // don't check focal length to allow distortion correction for lenses without chip, also pass dummy focal length 1 in case of 0 - LCPMapper map(pLCPProf, max(idata->getFocalLen(), 1.0), idata->getFocalLen35mm(), idata->getFocusDist(), idata->getFNumber(), true, false, W, H, coarse, -1); + if (pLCPProf) { // don't check focal length to allow distortion correction for lenses without chip, also pass dummy focal length 1 in case of 0 + pmap.reset(new LCPMapper(pLCPProf, max(idata->getFocalLen(), 1.0), idata->getFocalLen35mm(), idata->getFocusDist(), idata->getFNumber(), true, false, W, H, coarse, -1)); + } + } + 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) { @@ -1913,42 +1920,16 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le } } - // check if it is an olympus E camera, if yes, compute G channel pre-compensation factors + // check if it is an olympus E camera or green equilibration is enabled. If yes, compute G channel pre-compensation factors if ( ri->getSensorType() == ST_BAYER && (raw.bayersensor.greenthresh || (((idata->getMake().size() >= 7 && idata->getMake().substr(0, 7) == "OLYMPUS" && idata->getModel()[0] == 'E') || (idata->getMake().size() >= 9 && idata->getMake().substr(0, 9) == "Panasonic")) && raw.bayersensor.method != RAWParams::BayerSensor::methodstring[ RAWParams::BayerSensor::vng4])) ) { // global correction - int ng1 = 0, ng2 = 0, i = 0; - double avgg1 = 0., avgg2 = 0.; - -#ifdef _OPENMP - #pragma omp parallel for default(shared) private(i) reduction(+: ng1, ng2, avgg1, avgg2) -#endif - - for (i = border; i < H - border; i++) - for (int j = border; j < W - border; j++) - if (ri->ISGREEN(i, j)) { - if (i & 1) { - avgg2 += rawData[i][j]; - ng2++; - } else { - avgg1 += rawData[i][j]; - ng1++; - } - } - - double corrg1 = ((double)avgg1 / ng1 + (double)avgg2 / ng2) / 2.0 / ((double)avgg1 / ng1); - double corrg2 = ((double)avgg1 / ng1 + (double)avgg2 / ng2) / 2.0 / ((double)avgg2 / ng2); - -#ifdef _OPENMP - #pragma omp parallel for default(shared) -#endif - - for (int i = border; i < H - border; i++) - for (int j = border; j < W - border; j++) - if (ri->ISGREEN(i, j)) { - float currData; - currData = (float)(rawData[i][j] * ((i & 1) ? corrg2 : corrg1)); - rawData[i][j] = (currData); - } + if(numFrames == 4) { + for(int i = 0; i < 4; ++i) { + green_equilibrate_global(*rawDataFrames[i]); + } + } else { + green_equilibrate_global(rawData); + } } if ( ri->getSensorType() == ST_BAYER && raw.bayersensor.greenthresh > 0) { @@ -1959,10 +1940,10 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le if(numFrames == 4) { for(int i = 0; i < 4; ++i) { - green_equilibrate(0.01 * (raw.bayersensor.greenthresh), *rawDataFrames[i]); + green_equilibrate(0.01 * raw.bayersensor.greenthresh, *rawDataFrames[i]); } } else { - green_equilibrate(0.01 * (raw.bayersensor.greenthresh), rawData); + green_equilibrate(0.01 * raw.bayersensor.greenthresh, rawData); } } @@ -2022,7 +2003,7 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le double clip = 0; int brightness, contrast, black, hlcompr, hlcomprthresh; getAutoExpHistogram (aehist, aehistcompr); - ImProcFunctions::getAutoExp (aehist, aehistcompr, getDefGain(), clip, dirpyrdenoiseExpComp, brightness, contrast, black, hlcompr, hlcomprthresh); + ImProcFunctions::getAutoExp (aehist, aehistcompr, clip, dirpyrdenoiseExpComp, brightness, contrast, black, hlcompr, hlcomprthresh); } t2.set(); @@ -2051,7 +2032,7 @@ void RawImageSource::demosaic(const RAWParams &raw) } else if (raw.bayersensor.method == RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::vng4] ) { vng4_demosaic (); } else if (raw.bayersensor.method == RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::ahd] ) { - ahd_demosaic (0, 0, W, H); + ahd_demosaic (); } else if (raw.bayersensor.method == RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::amaze] ) { amaze_demosaic_RT (0, 0, W, H, rawData, red, green, blue); } else if (raw.bayersensor.method == RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::pixelshift] ) { @@ -2065,7 +2046,7 @@ void RawImageSource::demosaic(const RAWParams &raw) } else if (raw.bayersensor.method == RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::lmmse]) { lmmse_interpolate_omp(W, H, rawData, red, green, blue, raw.bayersensor.lmmse_iterations); } else if (raw.bayersensor.method == RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::fast] ) { - fast_demosaic (0, 0, W, H); + fast_demosaic(); } else if (raw.bayersensor.method == RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::mono] ) { nodemosaic(true); } else { @@ -2136,8 +2117,8 @@ void RawImageSource::retinexPrepareBuffers(ColorManagementParams cmp, const Reti std::swap(pwr, gamm); } - int mode = 0, imax = 0; - Color::calcGamma(pwr, ts, mode, imax, g_a); // call to calcGamma with selected gamma and slope + int mode = 0; + Color::calcGamma(pwr, ts, mode, g_a); // call to calcGamma with selected gamma and slope // printf("g_a0=%f g_a1=%f g_a2=%f g_a3=%f g_a4=%f\n", g_a0,g_a1,g_a2,g_a3,g_a4); double start; @@ -2403,13 +2384,13 @@ void RawImageSource::retinex(ColorManagementParams cmp, const RetinexParams &deh double gamm = deh.gam; double gamm2 = gamm; double ts = deh.slope; - int mode = 0, imax = 0; + int mode = 0; if(gamm2 < 1.) { std::swap(pwr, gamm); } - Color::calcGamma(pwr, ts, mode, imax, g_a); // call to calcGamma with selected gamma and slope + Color::calcGamma(pwr, ts, mode, g_a); // call to calcGamma with selected gamma and slope double mul = 1. + g_a[4]; double add; diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index bc2589408..d2ce77fed 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -116,7 +116,7 @@ public: RawImageSource (); ~RawImageSource (); - int load (const Glib::ustring &fname, int imageNum = 0, bool batch = false); + int load (const Glib::ustring &fname); void preprocess (const RAWParams &raw, const LensProfParams &lensProf, const CoarseTransformParams& coarse, bool prepareDenoise = true); void demosaic (const RAWParams &raw); void retinex (ColorManagementParams cmp, const RetinexParams &deh, 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); @@ -128,7 +128,7 @@ public: void refinement_lassus (int PassCount); void refinement(int PassCount); - bool IsrgbSourceModified() const + bool isRGBSourceModified() const { return rgbSourceModified; // tracks whether cached rgb output of demosaic has been modified } @@ -138,7 +138,7 @@ public: void cfaboxblur (RawImage *riFlatFile, float* cfablur, int boxH, int boxW); void scaleColors (int winx, int winy, int winw, int winh, const RAWParams &raw, array2D &rawData); // raw for cblack - void getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const ToneCurveParams &hrp, const ColorManagementParams &cmp, const RAWParams &raw); + void getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const ToneCurveParams &hrp, const RAWParams &raw); eSensorType getSensorType () const { return ri != nullptr ? ri->getSensorType() : ST_NONE; @@ -166,9 +166,9 @@ public: return ri->get_rotateDegree(); } - ImageData* getImageData () + FrameData* getImageData (unsigned int frameNum) { - return idata; + return idata->getFrameData (frameNum); } ImageMatrices* getImageMatrices () { @@ -185,7 +185,7 @@ public: } void getAutoExpHistogram (LUTu & histogram, int& histcompr); void getRAWHistogram (LUTu & histRedRaw, LUTu & histGreenRaw, LUTu & histBlueRaw); - DCPProfile *getDCP(const ColorManagementParams &cmp, ColorTemp &wb, DCPProfile::ApplyState &as); + DCPProfile *getDCP(const ColorManagementParams &cmp, DCPProfile::ApplyState &as); void convertColorSpace(Imagefloat* image, const ColorManagementParams &cmp, const ColorTemp &wb); static bool findInputProfile(Glib::ustring inProfile, cmsHPROFILE embedded, std::string camName, DCPProfile **dcpProf, cmsHPROFILE& in); @@ -233,6 +233,7 @@ protected: void cfa_linedn (float linenoiselevel);//Emil's line denoise + void green_equilibrate_global (array2D &rawData); void green_equilibrate (float greenthresh, array2D &rawData);//Emil's green equilibration void nodemosaic(bool bw); @@ -244,9 +245,9 @@ protected: void igv_interpolate(int winw, int winh); void lmmse_interpolate_omp(int winw, int winh, array2D &rawData, array2D &red, array2D &green, array2D &blue, int iterations); void amaze_demosaic_RT(int winx, int winy, int winw, int winh, array2D &rawData, array2D &red, array2D &green, array2D &blue);//Emil's code for AMaZE - void fast_demosaic(int winx, int winy, int winw, int winh );//Emil's code for fast demosaicing + void fast_demosaic();//Emil's code for fast demosaicing void dcb_demosaic(int iterations, bool dcb_enhance); - void ahd_demosaic(int winx, int winy, int winw, int winh); + void ahd_demosaic(); void border_interpolate(unsigned int border, float (*image)[4], unsigned int start = 0, unsigned int end = 0); void border_interpolate2(int winw, int winh, int lborders); void dcb_initTileLimits(int &colMin, int &rowMin, int &colMax, int &rowMax, int x0, int y0, int border); diff --git a/rtengine/rawmetadatalocation.h b/rtengine/rawmetadatalocation.h index d029d2a13..40ac6cc3e 100644 --- a/rtengine/rawmetadatalocation.h +++ b/rtengine/rawmetadatalocation.h @@ -22,11 +22,19 @@ namespace rtengine { -struct RawMetaDataLocation { +class RawMetaDataLocation { + +public: int exifBase; int ciffBase; int ciffLength; + + RawMetaDataLocation () : exifBase(-1), ciffBase(-1), ciffLength(-1) {} + RawMetaDataLocation (int exifBase) : exifBase(exifBase), ciffBase(-1), ciffLength(-1) {} + RawMetaDataLocation (int ciffBase, int ciffLength) : exifBase(-1), ciffBase(ciffBase), ciffLength(ciffLength) {} + RawMetaDataLocation (int exifBase, int ciffBase, int ciffLength) : exifBase(exifBase), ciffBase(ciffBase), ciffLength(ciffLength) {} }; + } #endif diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index c106f4166..04afadb04 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -510,8 +510,13 @@ int refreshmap[rtengine::NUMOFEVENTS] = { LUMINANCECURVE, // EvCATtempsc LUMINANCECURVE, // EvCATgreensc LUMINANCECURVE, // EvCATybscen - LUMINANCECURVE // EvCATAutoyb - + LUMINANCECURVE, // EvCATAutoyb + DARKFRAME, // EvLensCorrMode + DARKFRAME, // EvLensCorrLensfunCamera + DARKFRAME, // EvLensCorrLensfunLens + ALLNORAW, // EvTMFattalEnabled + HDR, // EvTMFattalThreshold + HDR // EvTMFattalAmount }; diff --git a/rtengine/refreshmap.h b/rtengine/refreshmap.h index 8fd195e4e..83489694b 100644 --- a/rtengine/refreshmap.h +++ b/rtengine/refreshmap.h @@ -20,23 +20,24 @@ #define __REFRESHMAP__ // Use M_VOID if you wish to update the proc params without updating the preview at all ! -#define M_VOID (1<<31) +#define M_VOID (1<<18) // Use M_MINUPDATE if you wish to update the preview without modifying the image (think about it like a "refreshPreview") // Must NOT be used with other event (i.e. will be used for MINUPDATE only) -#define M_MINUPDATE (1<<30) +#define M_MINUPDATE (1<<17) // Force high quality -#define M_HIGHQUAL (1<<29) +#define M_HIGHQUAL (1<<16) // Elementary functions that can be done to // the preview image when an event occurs -#define M_SPOT (1<<14) -#define M_MONITOR (1<<13) -#define M_RETINEX (1<<12) -#define M_CROP (1<<11) -#define M_PREPROC (1<<10) -#define M_RAW (1<<9) -#define M_INIT (1<<8) -#define M_LINDENOISE (1<<7) +#define M_SPOT (1<<15) +#define M_MONITOR (1<<14) +#define M_RETINEX (1<<13) +#define M_CROP (1<<12) +#define M_PREPROC (1<<11) +#define M_RAW (1<<10) +#define M_INIT (1<<9) +#define M_LINDENOISE (1<<8) +#define M_HDR (1<<7) #define M_TRANSFORM (1<<6) #define M_BLURMAP (1<<5) #define M_AUTOEXP (1<<4) @@ -47,22 +48,23 @@ // Bitfield of functions to do to the preview image when an event occurs // Use those or create new ones for your new events -#define FIRST (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_SPOT|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR|M_MONITOR) // without HIGHQUAL -#define ALL (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_SPOT|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) // without HIGHQUAL -#define DARKFRAME (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_SPOT|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define FLATFIELD (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_SPOT|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define DEMOSAIC (M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_SPOT|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define ALLNORAW (M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_SPOT|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define TRANSFORM (M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_SPOT|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define AUTOEXP (M_AUTOEXP|M_SPOT|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define SPOT (M_SPOT|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define RGBCURVE (M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define LUMINANCECURVE (M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define SHARPENING (M_LUMINANCE|M_COLOR) -#define IMPULSEDENOISE (M_LUMINANCE|M_COLOR) -#define DEFRINGE (M_LUMINANCE|M_COLOR) -#define DIRPYRDENOISE (M_LUMINANCE|M_COLOR) -#define DIRPYREQUALIZER (M_LUMINANCE|M_COLOR) +#define FIRST (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_HDR|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_SPOT|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR|M_MONITOR) // without HIGHQUAL +#define ALL (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_HDR|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_SPOT|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) // without HIGHQUAL +#define DARKFRAME (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_HDR|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_SPOT|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define FLATFIELD (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_HDR|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_SPOT|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define DEMOSAIC (M_RAW|M_INIT|M_LINDENOISE|M_HDR|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_SPOT|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define ALLNORAW (M_INIT|M_LINDENOISE|M_HDR|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_SPOT|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define HDR (M_HDR|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_SPOT|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define TRANSFORM (M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_SPOT|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define AUTOEXP (M_AUTOEXP|M_SPOT|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define SPOT (M_SPOT|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define RGBCURVE (M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define LUMINANCECURVE (M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define SHARPENING (M_LUMINANCE|M_COLOR) +#define IMPULSEDENOISE (M_LUMINANCE|M_COLOR) +#define DEFRINGE (M_LUMINANCE|M_COLOR) +#define DIRPYRDENOISE (M_LUMINANCE|M_COLOR) +#define DIRPYREQUALIZER (M_LUMINANCE|M_COLOR) #define GAMMA M_MONITOR #define CROP M_CROP #define RESIZE M_VOID diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index 9ba794a1f..edf903352 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -19,6 +19,7 @@ #ifndef _RTENGINE_ #define _RTENGINE_ +#include "imageformat.h" #include "rt_math.h" #include "procparams.h" #include "procevents.h" @@ -47,59 +48,84 @@ namespace rtengine class IImage8; class IImage16; class IImagefloat; +class ImageSource; /** - * This class represents provides functions to obtain exif and IPTC metadata information - * from the image file + * This class provides functions to obtain exif and IPTC metadata information + * from any of the sub-frame of an image file */ -class ImageMetaData +class FramesMetaData { public: + /** @return Returns the number of root Metadata */ + virtual unsigned int getRootCount () const = 0; + /** @return Returns the number of frame contained in the file based on Metadata */ + virtual unsigned int getFrameCount () const = 0; + /** Checks the availability of exif metadata tags. * @return Returns true if image contains exif metadata tags */ - virtual bool hasExif () const = 0; + virtual bool hasExif (unsigned int frame = 0) const = 0; /** Returns the directory of exif metadata tags. + * @param root root number in the metadata tree * @return The directory of exif metadata tags */ - virtual const rtexif::TagDirectory* getExifData () const = 0; + virtual rtexif::TagDirectory* getRootExifData (unsigned int root = 0) const = 0; + /** Returns the directory of exif metadata tags. + * @param frame frame number in the metadata tree + * @return The directory of exif metadata tags */ + virtual rtexif::TagDirectory* getFrameExifData (unsigned int frame = 0) const = 0; + /** Returns the directory of exif metadata tags containing at least the 'Make' tag for the requested frame. + * If no usable metadata exist in the frame, send back the best TagDirectory describing the frame content. + * @param imgSource rawimage that we want the metadata from + * @param rawParams RawParams to select the frame number + * @return The directory of exif metadata tags containing at least the 'Make' tag */ + virtual rtexif::TagDirectory* getBestExifData (ImageSource *imgSource, procparams::RAWParams *rawParams) const = 0; /** Checks the availability of IPTC tags. * @return Returns true if image contains IPTC tags */ - virtual bool hasIPTC () const = 0; + virtual bool hasIPTC (unsigned int frame = 0) const = 0; /** Returns the directory of IPTC tags. * @return The directory of IPTC tags */ - virtual const procparams::IPTCPairs getIPTCData () const = 0; + virtual procparams::IPTCPairs getIPTCData (unsigned int frame = 0) const = 0; /** @return a struct containing the date and time of the image */ - virtual struct tm getDateTime () const = 0; + virtual tm getDateTime (unsigned int frame = 0) const = 0; /** @return a timestamp containing the date and time of the image */ - virtual time_t getDateTimeAsTS() const = 0; + virtual time_t getDateTimeAsTS(unsigned int frame = 0) const = 0; /** @return the ISO of the image */ - virtual int getISOSpeed () const = 0; + virtual int getISOSpeed (unsigned int frame = 0) const = 0; /** @return the F number of the image */ - virtual double getFNumber () const = 0; + virtual double getFNumber (unsigned int frame = 0) const = 0; /** @return the focal length used at the exposure */ - virtual double getFocalLen () const = 0; + virtual double getFocalLen (unsigned int frame = 0) const = 0; /** @return the focal length in 35mm used at the exposure */ - virtual double getFocalLen35mm () const = 0; + virtual double getFocalLen35mm (unsigned int frame = 0) const = 0; /** @return the focus distance in meters, 0=unknown, 10000=infinity */ - virtual float getFocusDist () const = 0; + virtual float getFocusDist (unsigned int frame = 0) const = 0; /** @return the shutter speed */ - virtual double getShutterSpeed () const = 0; + virtual double getShutterSpeed (unsigned int frame = 0) const = 0; /** @return the exposure compensation */ - virtual double getExpComp () const = 0; + virtual double getExpComp (unsigned int frame = 0) const = 0; /** @return the maker of the camera */ - virtual std::string getMake () const = 0; + virtual std::string getMake (unsigned int frame = 0) const = 0; /** @return the model of the camera */ - virtual std::string getModel () const = 0; + virtual std::string getModel (unsigned int frame = 0) const = 0; - std::string getCamera () const + std::string getCamera (unsigned int frame = 0) const { - return getMake() + " " + getModel(); + return getMake(frame) + " " + getModel(frame); } /** @return the lens on the camera */ - virtual std::string getLens () const = 0; + virtual std::string getLens (unsigned int frame = 0) const = 0; /** @return the orientation of the image */ - virtual std::string getOrientation () const = 0; + virtual std::string getOrientation (unsigned int frame = 0) const = 0; + + /** @return true if the file is a PixelShift shot (Pentax bodies) */ + virtual bool getPixelShift (unsigned int frame = 0) const = 0; + /** @return false: not an HDR file ; true: single or multi-frame HDR file (e.g. Pentax HDR raw file or 32 bit float DNG file or Log compressed) */ + virtual bool getHDR (unsigned int frame = 0) const = 0; + /** @return the sample format based on MetaData */ + virtual IIOSampleFormat getSampleFormat (unsigned int frame = 0) const = 0; + /** Functions to convert between floating point and string representation of shutter and aperture */ static std::string apertureToString (double aperture); /** Functions to convert between floating point and string representation of shutter and aperture */ @@ -111,14 +137,15 @@ public: /** Functions to convert between floating point and string representation of exposure compensation */ static std::string expcompToString (double expcomp, bool maskZeroexpcomp); - virtual ~ImageMetaData () {} + virtual ~FramesMetaData () = default; /** Reads metadata from file. * @param fname is the name of the file - * @param rml is a struct containing information about metadata location. Use it only for raw files. In case - * of jpgs and tiffs pass a NULL pointer. + * @param rml is a struct containing information about metadata location of the first frame. + * Use it only for raw files. In caseof jpgs and tiffs pass a NULL pointer. + * @param firstFrameOnly must be true to get the MetaData of the first frame only, e.g. for a PixelShift file. * @return The metadata */ - static ImageMetaData* fromFile (const Glib::ustring& fname, RawMetaDataLocation* rml); + static FramesMetaData* fromFile (const Glib::ustring& fname, std::unique_ptr rml, bool firstFrameOnly = false); }; /** This listener interface is used to indicate the progress of time consuming operations */ @@ -157,9 +184,9 @@ public: /** Returns the embedded icc profile of the image. * @return The handle of the embedded profile */ virtual cmsHPROFILE getEmbeddedProfile () = 0; - /** Returns a class providing access to the exif and iptc metadata tags of the image. - * @return An instance of the ImageMetaData class */ - virtual const ImageMetaData* getMetaData () = 0; + /** Returns a class providing access to the exif and iptc metadata tags of all frames of the image. + * @return An instance of the FramesMetaData class */ + virtual const FramesMetaData* getMetaData () = 0; /** This is a function used for internal purposes only. */ virtual ImageSource* getImageSource () = 0; /** This class has manual reference counting. You have to call this function each time to make a new reference to an instance. */ diff --git a/rtengine/rtlensfun.cc b/rtengine/rtlensfun.cc new file mode 100644 index 000000000..8216f0b83 --- /dev/null +++ b/rtengine/rtlensfun.cc @@ -0,0 +1,541 @@ +/* -*- C++ -*- + * + * This file is part of RawTherapee. + * + * Copyright (c) 2017 Alberto Griggio + * + * 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 "rtlensfun.h" +#include "settings.h" +#include + +namespace rtengine { + +extern const Settings *settings; + +//----------------------------------------------------------------------------- +// LFModifier +//----------------------------------------------------------------------------- + +LFModifier::~LFModifier() +{ + if (data_) { + data_->Destroy(); + } +} + + +LFModifier::operator bool() const +{ + return data_; +} + + +void LFModifier::correctDistortion(double &x, double &y, int cx, int cy, double scale) const +{ + if (!data_) { + return; + } + + float pos[2]; + float xx = x + cx; + float yy = y + cy; + if (swap_xy_) { + std::swap(xx, yy); + } + if (data_->ApplyGeometryDistortion(xx, yy, 1, 1, pos)) { + x = pos[0]; + y = pos[1]; + if (swap_xy_) { + std::swap(x, y); + } + x -= cx; + y -= cy; + } + x *= scale; + y *= scale; +} + + +bool LFModifier::isCACorrectionAvailable() const +{ + return (flags_ & LF_MODIFY_TCA); +} + +#ifdef __GNUC__ // silence warning, can be removed when function is implemented +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +void LFModifier::correctCA(double &x, double &y, int cx, int cy, int channel) const +{ + assert(channel >= 0 && channel <= 2); + + // agriggio: RT currently applies the CA correction per channel, whereas + // lensfun applies it to all the three channels simultaneously. This means + // we do the work 3 times, because each time we discard 2 of the 3 + // channels. We could consider caching the info to speed this up + x += cx; + y += cy; + + float pos[6]; + if (swap_xy_) { + std::swap(x, y); + } + data_->ApplySubpixelDistortion(x, y, 1, 1, pos); + x = pos[2*channel]; + y = pos[2*channel+1]; + if (swap_xy_) { + std::swap(x, y); + } + x -= cx; + y -= cy; +} + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + + +void LFModifier::processVignetteLine(int width, int y, float *line) const +{ + data_->ApplyColorModification(line, 0, y, width, 1, LF_CR_1(INTENSITY), 0); +} + + +void LFModifier::processVignetteLine3Channels(int width, int y, float *line) const +{ + data_->ApplyColorModification(line, 0, y, width, 1, LF_CR_3(RED, GREEN, BLUE), 0); +} + + +Glib::ustring LFModifier::getDisplayString() const +{ + if (!data_) { + return "NONE"; + } else { + Glib::ustring ret; + Glib::ustring sep = ""; + if (flags_ & LF_MODIFY_DISTORTION) { + ret += "distortion"; + sep = ", "; + } + if (flags_ & LF_MODIFY_VIGNETTING) { + ret += sep; + ret += "vignetting"; + sep = ", "; + } + if (flags_ & LF_MODIFY_TCA) { + ret += sep; + ret += "CA"; + sep = ", "; + } + if (flags_ & LF_MODIFY_SCALE) { + ret += sep; + ret += "autoscaling"; + } + return ret; + } +} + + +LFModifier::LFModifier(lfModifier *m, bool swap_xy, int flags): + data_(m), + swap_xy_(swap_xy), + flags_(flags) +{ +} + + +//----------------------------------------------------------------------------- +// LFCamera +//----------------------------------------------------------------------------- + +LFCamera::LFCamera(): + data_(nullptr) +{ +} + + +LFCamera::operator bool() const +{ + return data_; +} + + +Glib::ustring LFCamera::getMake() const +{ + if (data_) { + return data_->Maker; + } else { + return ""; + } +} + + +Glib::ustring LFCamera::getModel() const +{ + if (data_) { + return data_->Model; + } else { + return ""; + } +} + + +float LFCamera::getCropFactor() const +{ + if (data_) { + return data_->CropFactor; + } else { + return 0; + } +} + + +bool LFCamera::isFixedLens() const +{ + // per lensfun's main developer Torsten Bronger: + // "Compact camera mounts can be identified by the fact that the mount + // starts with a lowercase letter" + return data_ && data_->Mount && std::islower(data_->Mount[0]); +} + + +Glib::ustring LFCamera::getDisplayString() const +{ + if (data_) { + return getMake() + ' ' + getModel(); + } else { + return "---"; + } +} + + +//----------------------------------------------------------------------------- +// LFLens +//----------------------------------------------------------------------------- + +LFLens::LFLens(): + data_(nullptr) +{ +} + + +LFLens::operator bool() const +{ + return data_; +} + + +Glib::ustring LFLens::getMake() const +{ + if (data_) { + return data_->Maker; + } else { + return ""; + } +} + + +Glib::ustring LFLens::getLens() const +{ + if (data_) { + return Glib::ustring(data_->Maker) + ' ' + data_->Model; + } else { + return "---"; + } +} + + +float LFLens::getCropFactor() const +{ + if (data_) { + return data_->CropFactor; + } else { + return 0; + } +} + +bool LFLens::hasVignettingCorrection() const +{ + if (data_) { + return data_->CalibVignetting; + } else { + return false; + } +} + +bool LFLens::hasDistortionCorrection() const +{ + if (data_) { + return data_->CalibDistortion; + } else { + return false; + } +} + +bool LFLens::hasCACorrection() const +{ + if (data_) { + return data_->CalibTCA; + } else { + return false; + } +} + + +//----------------------------------------------------------------------------- +// LFDatabase +//----------------------------------------------------------------------------- + +LFDatabase LFDatabase::instance_; + + +bool LFDatabase::init(const Glib::ustring &dbdir) +{ + instance_.data_ = lfDatabase::Create(); + + if (settings->verbose) { + std::cout << "Loading lensfun database from "; + if (dbdir.empty()) { + std::cout << "the default directories"; + } else { + std::cout << "'" << dbdir << "'"; + } + std::cout << "..." << std::flush; + } + + bool ok = false; + if (dbdir.empty()) { + ok = (instance_.data_->Load() == LF_NO_ERROR); + } else { + ok = instance_.LoadDirectory(dbdir.c_str()); + } + + if (settings->verbose) { + std::cout << (ok ? "OK" : "FAIL") << std::endl; + } + + return ok; +} + + +bool LFDatabase::LoadDirectory(const char *dirname) +{ +#if RT_LENSFUN_HAS_LOAD_DIRECTORY + return instance_.data_->LoadDirectory(dirname); +#else + // backported from lensfun 0.3.x + bool database_found = false; + + GDir *dir = g_dir_open (dirname, 0, NULL); + if (dir) + { + GPatternSpec *ps = g_pattern_spec_new ("*.xml"); + if (ps) + { + const gchar *fn; + while ((fn = g_dir_read_name (dir))) + { + size_t sl = strlen (fn); + if (g_pattern_match (ps, sl, fn, NULL)) + { + gchar *ffn = g_build_filename (dirname, fn, NULL); + /* Ignore errors */ + if (data_->Load (ffn) == LF_NO_ERROR) + database_found = true; + g_free (ffn); + } + } + g_pattern_spec_free (ps); + } + g_dir_close (dir); + } + + return database_found; +#endif +} + + +LFDatabase::LFDatabase(): + data_(nullptr) +{ +} + + +LFDatabase::~LFDatabase() +{ + if (data_) { + data_->Destroy(); + } +} + + +const LFDatabase *LFDatabase::getInstance() +{ + return &instance_; +} + + +std::vector LFDatabase::getCameras() const +{ + std::vector ret; + if (data_) { + auto cams = data_->GetCameras(); + while (*cams) { + ret.emplace_back(); + ret.back().data_ = *cams; + ++cams; + } + } + return ret; +} + + +std::vector LFDatabase::getLenses() const +{ + std::vector ret; + if (data_) { + auto lenses = data_->GetLenses(); + while (*lenses) { + ret.emplace_back(); + ret.back().data_ = *lenses; + ++lenses; + } + } + return ret; +} + + +LFCamera LFDatabase::findCamera(const Glib::ustring &make, const Glib::ustring &model) const +{ + LFCamera ret; + if (data_) { + auto found = data_->FindCamerasExt(make.c_str(), model.c_str()); + if (found) { + ret.data_ = found[0]; + lf_free(found); + } + } + return ret; +} + + +LFLens LFDatabase::findLens(const LFCamera &camera, const Glib::ustring &name) const +{ + LFLens ret; + if (data_) { + auto found = data_->FindLenses(camera.data_, nullptr, name.c_str()); + for (size_t pos = 0; !found && pos < name.size(); ) { + // try to split the maker from the model of the lens -- we have to + // guess a bit here, since there are makers with a multi-word name + // (e.g. "Leica Camera AG") + if (name.find("f/", pos) == 0) { + break; // no need to search further + } + Glib::ustring make, model; + auto i = name.find(' ', pos); + if (i != Glib::ustring::npos) { + make = name.substr(0, i); + model = name.substr(i+1); + found = data_->FindLenses(camera.data_, make.c_str(), model.c_str()); + pos = i+1; + } else { + break; + } + } + if (!found && camera && camera.isFixedLens()) { + found = data_->FindLenses(camera.data_, nullptr, ""); + } + if (found) { + ret.data_ = found[0]; + lf_free(found); + } + } + return ret; +} + + +std::unique_ptr LFDatabase::getModifier(const LFCamera &camera, const LFLens &lens, + float focalLen, float aperture, float focusDist, + int width, int height, bool swap_xy) const +{ + std::unique_ptr ret; + if (data_) { + if (camera && lens) { + lfModifier *mod = lfModifier::Create(lens.data_, camera.getCropFactor(), width, height); + int flags = LF_MODIFY_DISTORTION | LF_MODIFY_SCALE | LF_MODIFY_TCA; + if (aperture > 0) { + flags |= LF_MODIFY_VIGNETTING; + } + flags = mod->Initialize(lens.data_, LF_PF_F32, focalLen, aperture, focusDist > 0 ? focusDist : 1000, 0.0, LF_RECTILINEAR, flags, false); + ret.reset(new LFModifier(mod, swap_xy, flags)); + } + } + return ret; +} + + +std::unique_ptr LFDatabase::findModifier(const LensProfParams &lensProf, const FramesMetaData *idata, int width, int height, const CoarseTransformParams &coarse, int rawRotationDeg) +{ + const LFDatabase *db = getInstance(); + Glib::ustring make, model, lens; + float focallen = idata->getFocalLen(); + if (lensProf.lfAutoMatch()) { + if (focallen <= 0) { + return nullptr; + } + make = idata->getMake(); + model = idata->getModel(); + lens = idata->getLens(); + } else { + make = lensProf.lfCameraMake; + model = lensProf.lfCameraModel; + lens = lensProf.lfLens; + } + LFCamera c = db->findCamera(make, model); + LFLens l = db->findLens(lensProf.lfAutoMatch() ? c : LFCamera(), lens); + if (focallen <= 0 && l.data_ && l.data_->MinFocal == l.data_->MaxFocal) { + focallen = l.data_->MinFocal; + } + if (focallen <= 0) { + return nullptr; + } + bool swap_xy = false; + if (rawRotationDeg >= 0) { + int rot = (coarse.rotate + rawRotationDeg) % 360; + swap_xy = (rot == 90 || rot == 270); + if (swap_xy) { + std::swap(width, height); + } + } + + std::unique_ptr ret = db->getModifier(c, l, idata->getFocalLen(), idata->getFNumber(), idata->getFocusDist(), width, height, swap_xy); + + if (settings->verbose) { + std::cout << "LENSFUN:\n" + << " camera: " << c.getDisplayString() << "\n" + << " lens: " << l.getDisplayString() << "\n" + << " correction: " + << (ret ? ret->getDisplayString() : "NONE") << std::endl; + } + + return ret; +} + + +} // namespace rtengine diff --git a/rtengine/rtlensfun.h b/rtengine/rtlensfun.h new file mode 100644 index 000000000..7690ef544 --- /dev/null +++ b/rtengine/rtlensfun.h @@ -0,0 +1,128 @@ +/* -*- C++ -*- + * + * This file is part of RawTherapee. + * + * Copyright (c) 2017 Alberto Griggio + * + * 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 . + */ + +#pragma once + +#include +#include + +#include + +#include + +#include "lcp.h" +#include "noncopyable.h" +#include "procparams.h" + +namespace rtengine { + +class LFModifier final : + public LensCorrection, + public NonCopyable +{ +public: + ~LFModifier(); + + explicit operator bool() const; + + void correctDistortion(double &x, double &y, int cx, int cy, double scale) const override; + bool isCACorrectionAvailable() const override; + void correctCA(double &x, double &y, int cx, int cy, int channel) const override; + void processVignetteLine(int width, int y, float *line) const override; + void processVignetteLine3Channels(int width, int y, float *line) const override; + + Glib::ustring getDisplayString() const; + +private: + LFModifier(lfModifier *m, bool swap_xy, int flags); + + friend class LFDatabase; + lfModifier *data_; + bool swap_xy_; + int flags_; +}; + +class LFCamera final +{ +public: + LFCamera(); + + explicit operator bool() const; + + Glib::ustring getMake() const; + Glib::ustring getModel() const; + float getCropFactor() const; + bool isFixedLens() const; + + Glib::ustring getDisplayString() const; + +private: + friend class LFDatabase; + const lfCamera *data_; +}; + +class LFLens final +{ +public: + LFLens(); + + explicit operator bool() const; + + Glib::ustring getMake() const; + Glib::ustring getLens() const; + Glib::ustring getDisplayString() const { return getLens(); } + float getCropFactor() const; + bool hasVignettingCorrection() const; + bool hasDistortionCorrection() const; + bool hasCACorrection() const; + +private: + friend class LFDatabase; + const lfLens *data_; +}; + +class LFDatabase final : + public NonCopyable +{ +public: + static bool init(const Glib::ustring &dbdir); + static const LFDatabase *getInstance(); + + ~LFDatabase(); + + std::vector getCameras() const; + std::vector getLenses() const; + LFCamera findCamera(const Glib::ustring &make, const Glib::ustring &model) const; + LFLens findLens(const LFCamera &camera, const Glib::ustring &name) const; + + static std::unique_ptr findModifier(const LensProfParams &lensProf, const FramesMetaData *idata, int width, int height, const CoarseTransformParams &coarse, int rawRotationDeg); + +private: + std::unique_ptr getModifier(const LFCamera &camera, const LFLens &lens, + float focalLen, float aperture, float focusDist, + int width, int height, bool swap_xy) const; + LFDatabase(); + bool LoadDirectory(const char *dirname); + + static LFDatabase instance_; + lfDatabase *data_; +}; + +} // namespace rtengine diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 511b17f9f..8adab4ec5 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -38,7 +38,6 @@ #include "improccoordinator.h" #include - namespace { @@ -247,7 +246,7 @@ Thumbnail* Thumbnail::loadFromImage (const Glib::ustring& fname, int &w, int &h, return tpp; } -Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, int &w, int &h, int fixwh, bool rotate, bool inspectorMode) +Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, eSensorType &sensorType, int &w, int &h, int fixwh, bool rotate, bool inspectorMode) { RawImage *ri = new RawImage (fname); unsigned int imageNum = 0; @@ -255,9 +254,12 @@ Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, RawMetaDataL if ( r ) { delete ri; + sensorType = ST_NONE; return nullptr; } + sensorType = ri->getSensorType(); + rml.exifBase = ri->get_exifBase(); rml.ciffBase = ri->get_ciffBase(); rml.ciffLength = ri->get_ciffLen(); @@ -378,7 +380,7 @@ RawMetaDataLocation Thumbnail::loadMetaDataFromRaw (const Glib::ustring& fname) return rml; } -Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, int &w, int &h, int fixwh, double wbEq, bool rotate, int imageNum) +Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, eSensorType &sensorType, int &w, int &h, int fixwh, double wbEq, bool rotate) { RawImage *ri = new RawImage (fname); unsigned int tempImageNum = 0; @@ -387,9 +389,12 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati if ( r ) { delete ri; + sensorType = ST_NONE; return nullptr; } + sensorType = ri->getSensorType(); + int width = ri->get_width(); int height = ri->get_height(); rtengine::Thumbnail* tpp = new rtengine::Thumbnail; @@ -653,70 +658,18 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati tpp->scale = (double) height / (rotate_90 ? w : h); } - // generate histogram for auto exposure + // generate histogram for auto exposure, also calculate autoWB tpp->aeHistCompression = 3; - tpp->aeHistogram (65536 >> tpp->aeHistCompression); + tpp->aeHistogram(65536 >> tpp->aeHistCompression); tpp->aeHistogram.clear(); - int radd = 4; - int gadd = 4; - int badd = 4; - if (!filter) { - radd = gadd = badd = 1; - } + const unsigned int add = filter ? 1 : 4 / ri->get_colors(); - for (int i = 8; i < height - 8; i++) { - int start, end; - - if (ri->get_FujiWidth() != 0) { - int fw = ri->get_FujiWidth(); - start = ABS (fw - i) + 8; - end = min (height + width - fw - i, fw + i) - 8; - } else { - start = 8; - end = width - 8; - } - - if (ri->get_colors() == 1) { - for (int j = start; j < end; j++) { - tpp->aeHistogram[ ((int) (image[i * width + j][0])) >> tpp->aeHistCompression] += radd; - tpp->aeHistogram[ ((int) (image[i * width + j][0])) >> tpp->aeHistCompression] += gadd; - tpp->aeHistogram[ ((int) (image[i * width + j][0])) >> tpp->aeHistCompression] += badd; - } - } else if (ri->getSensorType() == ST_BAYER) { - for (int j = start; j < end; j++) - if (FISGREEN (filter, i, j)) { - tpp->aeHistogram[ ((int) (tpp->camwbGreen * image[i * width + j][1])) >> tpp->aeHistCompression] += gadd; - } else if (FISRED (filter, i, j)) { - tpp->aeHistogram[ ((int) (tpp->camwbRed * image[i * width + j][0])) >> tpp->aeHistCompression] += radd; - } else if (FISBLUE (filter, i, j)) { - tpp->aeHistogram[ ((int) (tpp->camwbBlue * image[i * width + j][2])) >> tpp->aeHistCompression] += badd; - } - } else if (ri->getSensorType() == ST_FUJI_XTRANS) { - for (int j = start; j < end; j++) - if (ri->ISXTRANSGREEN (i, j)) { - tpp->aeHistogram[ ((int) (tpp->camwbGreen * image[i * width + j][1])) >> tpp->aeHistCompression] += gadd; - } else if (ri->ISXTRANSRED (i, j)) { - tpp->aeHistogram[ ((int) (tpp->camwbRed * image[i * width + j][0])) >> tpp->aeHistCompression] += radd; - } else if (ri->ISXTRANSBLUE (i, j)) { - tpp->aeHistogram[ ((int) (tpp->camwbBlue * image[i * width + j][2])) >> tpp->aeHistCompression] += badd; - } - } else { /* if(ri->getSensorType()==ST_FOVEON) */ - for (int j = start; j < end; j++) { - tpp->aeHistogram[ ((int) (image[i * width + j][0] * 2.f)) >> tpp->aeHistCompression] += radd; - tpp->aeHistogram[ ((int) (image[i * width + j][1])) >> tpp->aeHistCompression] += gadd; - tpp->aeHistogram[ ((int) (image[i * width + j][2] * 0.5f)) >> tpp->aeHistCompression] += badd; - } - } - } - - // generate autoWB - double avg_r = 0; - double avg_g = 0; - double avg_b = 0; - const float eps = 1e-5; //tolerance to avoid dividing by zero - - float rn = eps, gn = eps, bn = eps; + double pixSum[3] = {0.0}; + unsigned int n[3] = {0}; + const double compression = pow(2.0, tpp->aeHistCompression); + const double camWb[3] = {tpp->camwbRed / compression, tpp->camwbGreen / compression, tpp->camwbBlue / compression}; + const double clipval = 64000.0 / tpp->defGain; for (int i = 32; i < height - 32; i++) { int start, end; @@ -730,110 +683,118 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati end = width - 32; } - if (ri->getSensorType() == ST_BAYER) { + if (ri->get_colors() == 1) { for (int j = start; j < end; j++) { - if (!filter) { - double d = tpp->defGain * image[i * width + j][0]; - - if (d > 64000.) { - continue; - } - - avg_g += d; - avg_r += d; - avg_b += d; - rn++; - gn++; - bn++; - } else if (FISGREEN (filter, i, j)) { - double d = tpp->defGain * image[i * width + j][1]; - - if (d > 64000.) { - continue; - } - - avg_g += d; - gn++; - } else if (FISRED (filter, i, j)) { - double d = tpp->defGain * image[i * width + j][0]; - - if (d > 64000.) { - continue; - } - - avg_r += d; - rn++; - } else if (FISBLUE (filter, i, j)) { - double d = tpp->defGain * image[i * width + j][2]; - - if (d > 64000.) { - continue; - } - - avg_b += d; - bn++; + tpp->aeHistogram[image[i * width + j][0] >> tpp->aeHistCompression]++; + } + } else if (ri->getSensorType() == ST_BAYER) { + int c0 = ri->FC(i, start); + int c1 = ri->FC(i, start + 1); + int j = start; + int n0 = 0; + int n1 = 0; + double pixSum0 = 0.0; + double pixSum1 = 0.0; + for (; j < end - 1; j+=2) { + double v0 = image[i * width + j][c0]; + tpp->aeHistogram[(int)(camWb[c0] * v0)]++; + if (v0 <= clipval) { + pixSum0 += v0; + n0++; + } + double v1 = image[i * width + j + 1][c1]; + tpp->aeHistogram[(int)(camWb[c1] * v1)]++; + if (v1 <= clipval) { + pixSum1 += v1; + n1++; } } + if (j < end) { + double v0 = image[i * width + j][c0]; + tpp->aeHistogram[(int)(camWb[c0] * v0)]++; + if (v0 <= clipval) { + pixSum0 += v0; + n0++; + } + } + n[c0] += n0; + n[c1] += n1; + pixSum[c0] += pixSum0; + pixSum[c1] += pixSum1; } else if (ri->getSensorType() == ST_FUJI_XTRANS) { - for (int j = start; j < end; j++) { + int c[6]; + for(int cc = 0; cc < 6; ++cc) { + c[cc] = ri->XTRANSFC(i, start + cc); + } + int j = start; + for (; j < end - 5; j += 6) { + for(int cc = 0; cc < 6; ++cc) { + double d = image[i * width + j + cc][c[cc]]; + tpp->aeHistogram[(int)(camWb[c[cc]] * d)]++; + if (d <= clipval) { + pixSum[c[cc]] += d; + n[c[cc]]++; + } + } + } + for (; j < end; j++) { if (ri->ISXTRANSGREEN (i, j)) { - double d = tpp->defGain * image[i * width + j][1]; - - if (d > 64000.) { - continue; + double d = image[i * width + j][1]; + tpp->aeHistogram[(int)(camWb[1] * d)]++; + if (d <= clipval) { + pixSum[1] += d; + n[1]++; } - - avg_g += d; - gn++; } else if (ri->ISXTRANSRED (i, j)) { - double d = tpp->defGain * image[i * width + j][0]; - - if (d > 64000.) { - continue; + double d = image[i * width + j][0]; + tpp->aeHistogram[(int)(camWb[0] * d)]++; + if (d <= clipval) { + pixSum[0] += d; + n[0]++; } - - avg_r += d; - rn++; } else if (ri->ISXTRANSBLUE (i, j)) { - double d = tpp->defGain * image[i * width + j][2]; - - if (d > 64000.) { - continue; + double d = image[i * width + j][2]; + tpp->aeHistogram[(int)(camWb[2] * d)]++; + if (d <= clipval) { + pixSum[2] += d; + n[2]++; } - - avg_b += d; - bn++; } } } else { /* if(ri->getSensorType()==ST_FOVEON) */ for (int j = start; j < end; j++) { - double d = tpp->defGain * image[i * width + j][0]; - - if (d <= 64000.) { - avg_r += d; - rn++; + double r = image[i * width + j][0]; + if (r <= clipval) { + pixSum[0] += r; + n[0]++; } - - d = tpp->defGain * image[i * width + j][1]; - - if (d <= 64000.) { - avg_g += d; - gn++; + double g = image[i * width + j][1]; + if (g <= clipval) { + pixSum[1] += g; + n[1]++; } - - d = tpp->defGain * image[i * width + j][2]; - - if (d <= 64000.) { - avg_b += d; - bn++; + tpp->aeHistogram[((int)g) >> tpp->aeHistCompression] += add; + double b = image[i * width + j][2]; + if (b <= clipval) { + pixSum[2] += b; + n[2]++; } + tpp->aeHistogram[((int) (b * 0.5f)) >> tpp->aeHistCompression] += add; } } } - double reds = avg_r / rn * tpp->camwbRed; - double greens = avg_g / gn * tpp->camwbGreen; - double blues = avg_b / bn * tpp->camwbBlue; + if (ri->get_colors() == 1) { + pixSum[0] = pixSum[1] = pixSum[2] = 1.; + n[0] = n[1] = n[2] = 1; + } + pixSum[0] *= tpp->defGain; + pixSum[1] *= tpp->defGain; + pixSum[2] *= tpp->defGain; + + double reds = pixSum[0] / std::max(n[0], 1u) * tpp->camwbRed; + double greens = pixSum[1] / std::max(n[1], 1u) * tpp->camwbGreen; + double blues = pixSum[2] / std::max(n[2], 1u) * tpp->camwbBlue; tpp->redAWBMul = ri->get_rgb_cam (0, 0) * reds + ri->get_rgb_cam (0, 1) * greens + ri->get_rgb_cam (0, 2) * blues; tpp->greenAWBMul = ri->get_rgb_cam (1, 0) * reds + ri->get_rgb_cam (1, 1) * greens + ri->get_rgb_cam (1, 2) * blues; @@ -924,7 +885,7 @@ Thumbnail::~Thumbnail () } // Simple processing of RAW internal JPGs -IImage8* Thumbnail::quickProcessImage (const procparams::ProcParams& params, int rheight, rtengine::TypeInterpolation interp, double& myscale) +IImage8* Thumbnail::quickProcessImage (const procparams::ProcParams& params, int rheight, rtengine::TypeInterpolation interp) { int rwidth; @@ -954,9 +915,22 @@ IImage8* Thumbnail::quickProcessImage (const procparams::ProcParams& params, int } // Full thumbnail processing, second stage if complete profile exists -IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rheight, TypeInterpolation interp, std::string camName, - double focalLen, double focalLen35mm, float focusDist, float shutter, float fnumber, float iso, std::string expcomp_, double& myscale) +IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorType sensorType, int rheight, TypeInterpolation interp, const FramesMetaData *metadata, double& myscale) { + unsigned int imgNum = 0; + if (isRaw) { + if (sensorType == ST_BAYER) { + imgNum = rtengine::LIM(params.raw.bayersensor.imageNum, 0, metadata->getFrameCount() - 1); + } else if (sensorType == ST_FUJI_XTRANS) { + //imgNum = rtengine::LIM(params.raw.xtranssensor.imageNum, 0, metadata->getFrameCount() - 1) + } + } + std::string camName = metadata->getCamera(imgNum); + float shutter = metadata->getShutterSpeed(imgNum); + float fnumber = metadata->getFNumber(imgNum); + float iso = metadata->getISOSpeed(imgNum); + float fcomp = metadata->getExpComp(imgNum); + // check if the WB's equalizer value has changed if (wbEqual < (params.wb.equal - 5e-4) || wbEqual > (params.wb.equal + 5e-4) || wbTempBias < (params.wb.tempBias - 5e-4) || wbTempBias > (params.wb.tempBias + 5e-4)) { wbEqual = params.wb.equal; @@ -1072,6 +1046,10 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei ipf.firstAnalysis (baseImg, params, hist16); + if (params.fattal.enabled) { + ipf.ToneMapFattal02(baseImg); + } + // perform transform if (ipf.needsTransform()) { Imagefloat* trImg = new Imagefloat (fw, fh); @@ -1079,7 +1057,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei int origFH; double tscale = 0.0; getDimensions (origFW, origFH, tscale); - ipf.transform (baseImg, trImg, 0, 0, 0, 0, fw, fh, origFW * tscale + 0.5, origFH * tscale + 0.5, focalLen, focalLen35mm, focusDist, fnumber, 0, true); // Raw rotate degree not detectable here + ipf.transform (baseImg, trImg, 0, 0, 0, 0, fw, fh, origFW * tscale + 0.5, origFH * tscale + 0.5, metadata, 0, true); // Raw rotate degree not detectable here delete baseImg; baseImg = trImg; } @@ -1108,8 +1086,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei int hlcomprthresh = params.toneCurve.hlcomprthresh; if (params.toneCurve.autoexp && aeHistogram) { - double logDefGain = 0.0; - ipf.getAutoExp (aeHistogram, aeHistCompression, logDefGain, params.toneCurve.clip, expcomp, bright, contr, black, hlcompr, hlcomprthresh); + ipf.getAutoExp (aeHistogram, aeHistCompression, params.toneCurve.clip, expcomp, bright, contr, black, hlcompr, hlcomprthresh); } LUTf curve1 (65536); @@ -1135,8 +1112,8 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei ToneCurve customToneCurvebw2; CurveFactory::complexCurve (expcomp, black / 65535.0, hlcompr, hlcomprthresh, params.toneCurve.shcompr, bright, contr, - params.toneCurve.curveMode, params.toneCurve.curve, - params.toneCurve.curveMode2, params.toneCurve.curve2, + params.toneCurve.curve, + params.toneCurve.curve2, hist16, curve1, curve2, curve, dummy, customToneCurve1, customToneCurve2, 16); LUTf rCurve; @@ -1155,13 +1132,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei {wprof[1][0], wprof[1][1], wprof[1][2]}, {wprof[2][0], wprof[2][1], wprof[2][2]} }; - TMatrix wiprof = ICCStore::getInstance()->workingSpaceInverseMatrix (params.icm.working); - 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]} - }; - params.colorToning.getCurves (ctColorCurve, ctOpacityCurve, wp, wip, opautili); + params.colorToning.getCurves (ctColorCurve, ctOpacityCurve, wp, opautili); clToningcurve (65536); CurveFactory::curveToning (params.colorToning.clcurve, clToningcurve, scale == 1 ? 1 : 16); @@ -1272,17 +1243,12 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei customColCurve2, customColCurve3, 16); - int begh = 0, endh = labView->H; + bool execsharp = false; float d, dj, yb; float fnum = fnumber;// F number float fiso = iso;// ISO float fspeed = shutter;//speed - char * writ = new char[expcomp_.size() + 1];//convert expcomp_ to char - std::copy (expcomp_.begin(), expcomp_.end(), writ); - writ[expcomp_.size()] = '\0'; - float fcomp = atof (writ); //compensation + - - delete[] writ; float adap; if (fnum < 0.3f || fiso < 5.f || fspeed < 0.00001f) @@ -1310,7 +1276,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei CAMMean = NAN; CAMBrightCurveJ.dirty = true; CAMBrightCurveQ.dirty = true; - ipf.ciecam_02float (cieView, adap, begh, endh, 1, 2, labView, ¶ms, customColCurve1, customColCurve2, customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, sk, execsharp, d, dj, yb, rtt); + ipf.ciecam_02float (cieView, adap, 1, 2, labView, ¶ms, customColCurve1, customColCurve2, customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, sk, execsharp, d, dj, yb, rtt); delete cieView; } @@ -1420,7 +1386,7 @@ void Thumbnail::applyAutoExp (procparams::ProcParams& params) if (params.toneCurve.autoexp && aeHistogram) { ImProcFunctions ipf (¶ms, false); - ipf.getAutoExp (aeHistogram, aeHistCompression, log (defGain) / log (2.0), params.toneCurve.clip, params.toneCurve.expcomp, + ipf.getAutoExp (aeHistogram, aeHistCompression, params.toneCurve.clip, params.toneCurve.expcomp, params.toneCurve.brightness, params.toneCurve.contrast, params.toneCurve.black, params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh); } } @@ -1749,7 +1715,7 @@ unsigned char* Thumbnail::getGrayscaleHistEQ (int trim_width) return tmpdata; } -bool Thumbnail::writeImage (const Glib::ustring& fname, int format) +bool Thumbnail::writeImage (const Glib::ustring& fname) { if (!thumbImg) { diff --git a/rtengine/rtthumbnail.h b/rtengine/rtthumbnail.h index c40a226c4..2ee08de50 100644 --- a/rtengine/rtthumbnail.h +++ b/rtengine/rtthumbnail.h @@ -71,14 +71,13 @@ public: void init (); - IImage8* processImage (const procparams::ProcParams& pparams, int rheight, TypeInterpolation interp, std::string camName, - double focalLen, double focalLen35mm, float focusDist, float shutter, float fnumber, float iso, std::string expcomp_, double& scale); - IImage8* quickProcessImage (const procparams::ProcParams& pparams, int rheight, TypeInterpolation interp, double& scale); + IImage8* processImage (const procparams::ProcParams& pparams, eSensorType sensorType, int rheight, TypeInterpolation interp, const FramesMetaData *metadata, double& scale); + IImage8* quickProcessImage (const procparams::ProcParams& pparams, int rheight, TypeInterpolation interp); int getImageWidth (const procparams::ProcParams& pparams, int rheight, float &ratio); void getDimensions (int& w, int& h, double& scaleFac); - static Thumbnail* loadQuickFromRaw (const Glib::ustring& fname, rtengine::RawMetaDataLocation& rml, int &w, int &h, int fixwh, bool rotate, bool inspectorMode = false); - static Thumbnail* loadFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, int &w, int &h, int fixwh, double wbEq, bool rotate, int imageNum); + static Thumbnail* loadQuickFromRaw (const Glib::ustring& fname, rtengine::RawMetaDataLocation& rml, eSensorType &sensorType, int &w, int &h, int fixwh, bool rotate, bool inspectorMode = false); + static Thumbnail* loadFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, eSensorType &sensorType, int &w, int &h, int fixwh, double wbEq, bool rotate); static Thumbnail* loadFromImage (const Glib::ustring& fname, int &w, int &h, int fixwh, double wbEq, bool inspectorMode = false); static RawMetaDataLocation loadMetaDataFromRaw (const Glib::ustring& fname); @@ -89,7 +88,7 @@ public: void applyAutoExp (procparams::ProcParams& pparams); unsigned char* getGrayscaleHistEQ (int trim_width); - bool writeImage (const Glib::ustring& fname, int format); + bool writeImage (const Glib::ustring& fname); bool readImage (const Glib::ustring& fname); bool readData (const Glib::ustring& fname); diff --git a/rtengine/settings.h b/rtengine/settings.h index ada63400a..225503777 100644 --- a/rtengine/settings.h +++ b/rtengine/settings.h @@ -92,6 +92,9 @@ public: double ed_low; double ed_lipinfl; double ed_lipampl; + + Glib::ustring lensfunDbDirectory; ///< The directory containing the lensfun database. If empty, the system defaults will be used (as described in http://lensfun.sourceforge.net/manual/dbsearch.html) + /** Creates a new instance of Settings. * @return a pointer to the new Settings instance. */ static Settings* create (); diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 1cb6e06fb..c8e933dd3 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -318,7 +318,7 @@ private: int beg_tileW = wcr * tileWskip + tileWskip / 2.f - crW / 2.f; int beg_tileH = hcr * tileHskip + tileHskip / 2.f - crH / 2.f; PreviewProps ppP (beg_tileW, beg_tileH, crW, crH, skipP); - imgsrc->getImage (currWB, tr, origCropPart, ppP, params.toneCurve, params.icm, params.raw ); + imgsrc->getImage (currWB, tr, origCropPart, ppP, params.toneCurve, params.raw ); //baseImg->getStdImage(currWB, tr, origCropPart, ppP, true, params.toneCurve); // we only need image reduced to 1/4 here @@ -538,7 +538,7 @@ private: for (int wcr = 0; wcr <= 2; wcr++) { for (int hcr = 0; hcr <= 2; hcr++) { PreviewProps ppP (coordW[wcr], coordH[hcr], crW, crH, 1); - imgsrc->getImage (currWB, tr, origCropPart, ppP, params.toneCurve, params.icm, params.raw); + imgsrc->getImage (currWB, tr, origCropPart, ppP, params.toneCurve, params.raw); //baseImg->getStdImage(currWB, tr, origCropPart, ppP, true, params.toneCurve); @@ -698,7 +698,7 @@ private: } baseImg = new Imagefloat (fw, fh); - imgsrc->getImage (currWB, tr, baseImg, pp, params.toneCurve, params.icm, params.raw); + imgsrc->getImage (currWB, tr, baseImg, pp, params.toneCurve, params.raw); if (pl) { pl->setProgress (0.50); @@ -718,7 +718,7 @@ private: LUTu aehist; int aehistcompr; imgsrc->getAutoExpHistogram (aehist, aehistcompr); - ipf.getAutoExp (aehist, aehistcompr, imgsrc->getDefGain(), params.toneCurve.clip, expcomp, bright, contr, black, hlcompr, hlcomprthresh); + ipf.getAutoExp (aehist, aehistcompr, params.toneCurve.clip, expcomp, bright, contr, black, hlcompr, hlcomprthresh); } // at this stage, we can flush the raw data to free up quite an important amount of memory @@ -778,9 +778,9 @@ private: // CurveFactory::denoiseLL(lldenoiseutili, denoiseParams.lcurve, Noisecurve,1); //denoiseParams.getCurves(noiseLCurve); // ipf.RGB_denoise(baseImg, baseImg, calclum, imgsrc->isRAW(), denoiseParams, params.defringe, imgsrc->getDirPyrDenoiseExpComp(), noiseLCurve, lldenoiseutili); - float chaut, redaut, blueaut, maxredaut, maxblueaut, nresi, highresi; + float nresi, highresi; int kall = 2; - ipf.RGB_denoise (kall, baseImg, baseImg, calclum, ch_M, max_r, max_b, imgsrc->isRAW(), denoiseParams, imgsrc->getDirPyrDenoiseExpComp(), noiseLCurve, noiseCCurve, chaut, redaut, blueaut, maxredaut, maxblueaut, nresi, highresi); + ipf.RGB_denoise (kall, baseImg, baseImg, calclum, ch_M, max_r, max_b, imgsrc->isRAW(), denoiseParams, imgsrc->getDirPyrDenoiseExpComp(), noiseLCurve, noiseCCurve, nresi, highresi); } @@ -810,15 +810,24 @@ private: ipf.firstAnalysis (baseImg, params, hist16); + if (params.fattal.enabled) { + ipf.ToneMapFattal02(baseImg); + } + // perform transform (excepted resizing) if (ipf.needsTransform()) { - Imagefloat* trImg = new Imagefloat (fw, fh); - ipf.transform (baseImg, trImg, 0, 0, 0, 0, fw, fh, fw, fh, imgsrc->getMetaData()->getFocalLen(), imgsrc->getMetaData()->getFocalLen35mm(), - imgsrc->getMetaData()->getFocusDist(), - imgsrc->getMetaData()->getFNumber(), - imgsrc->getRotateDegree(), true); - delete baseImg; - baseImg = trImg; + Imagefloat* trImg = nullptr; + if (ipf.needsLuminanceOnly()) { + trImg = baseImg; + } else { + trImg = new Imagefloat (fw, fh); + } + ipf.transform (baseImg, trImg, 0, 0, 0, 0, fw, fh, fw, fh, + imgsrc->getMetaData(), imgsrc->getRotateDegree(), true); + if(trImg != baseImg) { + delete baseImg; + baseImg = trImg; + } } } @@ -872,7 +881,7 @@ private: //if(params.blackwhite.enabled) params.toneCurve.hrenabled=false; CurveFactory::complexCurve (expcomp, black / 65535.0, hlcompr, hlcomprthresh, params.toneCurve.shcompr, bright, contr, - params.toneCurve.curveMode, params.toneCurve.curve, params.toneCurve.curveMode2, params.toneCurve.curve2, + params.toneCurve.curve, params.toneCurve.curve2, hist16, curve1, curve2, curve, dummy, customToneCurve1, customToneCurve2 ); CurveFactory::RGBCurve (params.rgbCurves.rcurve, rCurve, 1); @@ -888,13 +897,7 @@ private: {wprof[1][0], wprof[1][1], wprof[1][2]}, {wprof[2][0], wprof[2][1], wprof[2][2]} }; - TMatrix wiprof = ICCStore::getInstance()->workingSpaceInverseMatrix (params.icm.working); - 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]} - }; - params.colorToning.getCurves (ctColorCurve, ctOpacityCurve, wp, wip, opautili); + params.colorToning.getCurves (ctColorCurve, ctOpacityCurve, wp, opautili); clToningcurve (65536, 0); CurveFactory::curveToning (params.colorToning.clcurve, clToningcurve, 1); cl2Toningcurve (65536, 0); @@ -933,7 +936,7 @@ private: autor = -9000.f; // This will ask to compute the "auto" values for the B&W tool (have to be inferior to -5000) DCPProfile::ApplyState as; - DCPProfile *dcpProf = imgsrc->getDCP (params.icm, currWB, as); + DCPProfile *dcpProf = imgsrc->getDCP (params.icm, as); LUTu histToneCurve; @@ -1080,7 +1083,7 @@ private: CurveFactory::curveWavContL (wavcontlutili, params.wavelet.wavclCurve, wavclCurve,/* hist16C, dummy,*/ 1); if (params.wavelet.enabled) { - ipf.ip_wavelet (labView, labView, 2, WaveParams, wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, wavcontlutili, 1); + ipf.ip_wavelet (labView, labView, 2, WaveParams, wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, 1); } wavCLVCurve.Reset(); @@ -1088,7 +1091,6 @@ private: //Colorappearance and tone-mapping associated int f_w = 1, f_h = 1; - int begh = 0, endh = fh; if (params.colorappearance.tonecie || params.colorappearance.enabled) { f_w = fw; @@ -1096,8 +1098,7 @@ private: } CieImage *cieView = new CieImage (f_w, (f_h)); - begh = 0; - endh = fh; + CurveFactory::curveLightBrightColor ( params.colorappearance.curve, params.colorappearance.curve2, @@ -1111,10 +1112,16 @@ private: if (params.colorappearance.enabled) { double adap; - float fnum = imgsrc->getMetaData()->getFNumber ();// F number - float fiso = imgsrc->getMetaData()->getISOSpeed () ;// ISO - float fspeed = imgsrc->getMetaData()->getShutterSpeed () ;//speed - float fcomp = imgsrc->getMetaData()->getExpComp ();//compensation + - + int imgNum = 0; + if (imgsrc->getSensorType() == ST_BAYER) { + imgNum = params.raw.bayersensor.imageNum; + } else if (imgsrc->getSensorType() == ST_FUJI_XTRANS) { + //imgNum = params.raw.xtranssensor.imageNum; + } + float fnum = imgsrc->getMetaData()->getFNumber (imgNum); // F number + float fiso = imgsrc->getMetaData()->getISOSpeed (imgNum) ; // ISO + float fspeed = imgsrc->getMetaData()->getShutterSpeed (imgNum) ; //speed + float fcomp = imgsrc->getMetaData()->getExpComp (imgNum); //compensation + - if (fnum < 0.3f || fiso < 5.f || fspeed < 0.00001f) { adap = 2000.; @@ -1133,18 +1140,18 @@ private: if (params.sharpening.enabled) { if (settings->ciecamfloat) { float d, dj, yb; - ipf.ciecam_02float (cieView, float (adap), begh, endh, 1, 2, labView, ¶ms, customColCurve1, customColCurve2, customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, true, d, dj, yb, 1); + ipf.ciecam_02float (cieView, float (adap), 1, 2, labView, ¶ms, customColCurve1, customColCurve2, customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, true, d, dj, yb, 1); } else { - double dd, dj, yb; - ipf.ciecam_02 (cieView, adap, begh, endh, 1, 2, labView, ¶ms, customColCurve1, customColCurve2, customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, true, dd, dj, yb, 1); + double dd, dj; + ipf.ciecam_02 (cieView, adap, 1, 2, labView, ¶ms, customColCurve1, customColCurve2, customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, true, dd, dj, 1); } } else { if (settings->ciecamfloat) { float d, dj, yb; - ipf.ciecam_02float (cieView, float (adap), begh, endh, 1, 2, labView, ¶ms, customColCurve1, customColCurve2, customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, true, d, dj, yb, 1); + ipf.ciecam_02float (cieView, float (adap), 1, 2, labView, ¶ms, customColCurve1, customColCurve2, customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, true, d, dj, yb, 1); } else { - double dd, dj, yb; - ipf.ciecam_02 (cieView, adap, begh, endh, 1, 2, labView, ¶ms, customColCurve1, customColCurve2, customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, true, dd, dj, yb, 1); + double dd, dj; + ipf.ciecam_02 (cieView, adap, 1, 2, labView, ¶ms, customColCurve1, customColCurve2, customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, true, dd, dj, 1); } } } @@ -1236,7 +1243,7 @@ private: GammaValues ga; // if(params.blackwhite.enabled) params.toneCurve.hrenabled=false; - readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm, bwonly, &ga); + readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm, &ga); customGamma = true; //or selected Free gamma @@ -1250,7 +1257,7 @@ 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 - readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm, bwonly); + readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm); if (settings->verbose) { printf ("Output profile_: \"%s\"\n", params.icm.output.c_str()); @@ -1287,9 +1294,12 @@ private: } if (tunnelMetaData) { - readyImg->setMetadata (ii->getMetaData()->getExifData ()); + // 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 ()); } else { - readyImg->setMetadata (ii->getMetaData()->getExifData (), params.exif, params.iptc); + // 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); } diff --git a/rtengine/stdimagesource.cc b/rtengine/stdimagesource.cc index 87f25a497..61bf90b31 100644 --- a/rtengine/stdimagesource.cc +++ b/rtengine/stdimagesource.cc @@ -102,7 +102,7 @@ void StdImageSource::getSampleFormat (const Glib::ustring &fname, IIOSampleForma * and RT's image data type (Image8, Image16 and Imagefloat), then it will * load the image into it */ -int StdImageSource::load (const Glib::ustring &fname, int imageNum, bool batch) +int StdImageSource::load (const Glib::ustring &fname) { fileName = fname; @@ -158,7 +158,7 @@ int StdImageSource::load (const Glib::ustring &fname, int imageNum, bool batch) embProfile = img->getEmbeddedProfile (); - idata = new ImageData (fname); + idata = new FramesData (fname); if (idata->hasExif()) { int deg = 0; @@ -187,7 +187,7 @@ int StdImageSource::load (const Glib::ustring &fname, int imageNum, bool batch) return 0; } -void StdImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const ToneCurveParams &hrp, const ColorManagementParams &cmp, const RAWParams &raw) +void StdImageSource::getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const ToneCurveParams &hrp, const RAWParams &raw) { // the code will use OpenMP as of now. diff --git a/rtengine/stdimagesource.h b/rtengine/stdimagesource.h index 330c08244..304bc3d8d 100644 --- a/rtengine/stdimagesource.h +++ b/rtengine/stdimagesource.h @@ -42,8 +42,8 @@ public: StdImageSource (); ~StdImageSource (); - int load (const Glib::ustring &fname, int imageNum = 0, bool batch = false); - void getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const ToneCurveParams &hrp, const ColorManagementParams &cmp, const RAWParams &raw); + int load (const Glib::ustring &fname); + void getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const ToneCurveParams &hrp, const RAWParams &raw); ColorTemp getWB () const { return wb; @@ -68,9 +68,9 @@ public: void getFullSize (int& w, int& h, int tr = TR_NONE); void getSize (const PreviewProps &pp, int& w, int& h); - ImageData* getImageData () + FrameData* getImageData (unsigned int frameNum) { - return idata; + return idata->getFrameData (frameNum); } ImageIO* getImageIO () { @@ -93,7 +93,7 @@ public: void convertColorSpace(Imagefloat* image, const ColorManagementParams &cmp, const ColorTemp &wb);// RAWParams raw will not be used for non-raw files (see imagesource.h) static void colorSpaceConversion (Imagefloat* im, const ColorManagementParams &cmp, cmsHPROFILE embedded, IIOSampleFormat sampleFormat); - bool IsrgbSourceModified() const + bool isRGBSourceModified() const { return rgbSourceModified; } diff --git a/rtengine/tmo_fattal02.cc b/rtengine/tmo_fattal02.cc new file mode 100644 index 000000000..0dff22a54 --- /dev/null +++ b/rtengine/tmo_fattal02.cc @@ -0,0 +1,1363 @@ +/* -*- C++ -*- + * + * This file is part of RawTherapee. + * + * Ported from LuminanceHDR by Alberto Griggio + * + * 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 . + */ + +/** + * @file tmo_fattal02.cpp + * @brief TMO: Gradient Domain High Dynamic Range Compression + * + * Implementation of Gradient Domain High Dynamic Range Compression + * by Raanan Fattal, Dani Lischinski, Michael Werman. + * + * @author Grzegorz Krawczyk, + * + * + * This file is a part of LuminanceHDR package, based on pfstmo. + * ---------------------------------------------------------------------- + * Copyright (C) 2003,2004 Grzegorz Krawczyk + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * ---------------------------------------------------------------------- + * + * $Id: tmo_fattal02.cpp,v 1.3 2008/11/04 23:43:08 rafm Exp $ + */ + + +#ifdef _OPENMP +#include +#endif +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "array2D.h" +#include "improcfun.h" +#include "settings.h" +#include "iccstore.h" +//#define BENCHMARK +#include "StopWatch.h" +#include "sleef.c" +#include "opthelper.h" +namespace rtengine +{ + +/****************************************************************************** + * RT code + ******************************************************************************/ + +extern const Settings *settings; +extern MyMutex *fftwMutex; + +using namespace std; + +namespace +{ + +class Array2Df: public array2D +{ + typedef array2D Super; +public: + Array2Df(): Super() {} + Array2Df (int w, int h): Super (w, h) {} + + float &operator() (int w, int h) + { + return (*this)[h][w]; + } + + const float &operator() (int w, int h) const + { + return (*this)[h][w]; + } + + float &operator() (int i) + { + return static_cast (*this)[i]; + } + + const float &operator() (int i) const + { + return const_cast (*this).operator() (i); + } + + int getRows() const + { + return const_cast (*this).height(); + } + + int getCols() const + { + return const_cast (*this).width(); + } + + float *data() + { + return static_cast (*this); + } + + const float *data() const + { + return const_cast (*this).data(); + } +}; + +// upper bound on image dimension used in tmo_fattal02 -- see the comment there +const int RT_dimension_cap = 1920; + +void rescale_bilinear (const Array2Df &src, Array2Df &dst, bool multithread); + + +/****************************************************************************** + * Luminance HDR code (modifications are marked with an RT comment) + ******************************************************************************/ + +void downSample (const Array2Df& A, Array2Df& B) +{ + const int width = B.getCols(); + const int height = B.getRows(); + + // Note, I've uncommented all omp directives. They are all ok but are + // applied to too small problems and in total don't lead to noticable + // speed improvements. The main issue is the pde solver and in case of the + // fft solver uses optimised threaded fftw routines. + //#pragma omp parallel for + for ( int y = 0 ; y < height ; y++ ) { + for ( int x = 0 ; x < width ; x++ ) { + float p = A (2 * x, 2 * y); + p += A (2 * x + 1, 2 * y); + p += A (2 * x, 2 * y + 1); + p += A (2 * x + 1, 2 * y + 1); + B (x, y) = p * 0.25f; // p / 4.0f; + } + } +} + +void gaussianBlur (const Array2Df& I, Array2Df& L) +{ + const int width = I.getCols(); + const int height = I.getRows(); + + if (width < 3 || height < 3) { + if (&I != &L) { + for (int i = 0, n = width * height; i < n; ++i) { + L (i) = I (i); + } + } + + return; + } + + Array2Df T (width, height); + + //--- X blur + #pragma omp parallel for shared(I, T) + + for ( int y = 0 ; y < height ; y++ ) { + for ( int x = 1 ; x < width - 1 ; x++ ) { + float t = 2.f * I (x, y); + t += I (x - 1, y); + t += I (x + 1, y); + T (x, y) = t * 0.25f; // t / 4.f; + } + + T (0, y) = ( 3.f * I (0, y) + I (1, y) ) * 0.25f; // / 4.f; + T (width - 1, y) = ( 3.f * I (width - 1, y) + I (width - 2, y) ) * 0.25f; // / 4.f; + } + + //--- Y blur + #pragma omp parallel for + + for ( int x = 0 ; x < width - 7 ; x += 8 ) { + for ( int y = 1 ; y < height - 1 ; y++ ) { + for (int xx = 0; xx < 8; ++xx) { + float t = 2.f * T (x + xx, y); + t += T (x + xx, y - 1); + t += T (x + xx, y + 1); + L (x + xx, y) = t * 0.25f; // t/4.0f; + } + } + + for (int xx = 0; xx < 8; ++xx) { + L (x + xx, 0) = ( 3.f * T (x + xx, 0) + T (x + xx, 1) ) * 0.25f; // / 4.0f; + L (x + xx, height - 1) = ( 3.f * T (x + xx, height - 1) + T (x + xx, height - 2) ) * 0.25f; // / 4.0f; + } + } + + for ( int x = width - (width % 8) ; x < width ; x++ ) { + for ( int y = 1 ; y < height - 1 ; y++ ) { + float t = 2.f * T (x, y); + t += T (x, y - 1); + t += T (x, y + 1); + L (x, y) = t * 0.25f; // t/4.0f; + } + + L (x, 0) = ( 3.f * T (x, 0) + T (x, 1) ) * 0.25f; // / 4.0f; + L (x, height - 1) = ( 3.f * T (x, height - 1) + T (x, height - 2) ) * 0.25f; // / 4.0f; + } +} + +void createGaussianPyramids ( Array2Df* H, Array2Df** pyramids, int nlevels) +{ + int width = H->getCols(); + int height = H->getRows(); + const int size = width * height; + + pyramids[0] = new Array2Df (width, height); + +//#pragma omp parallel for shared(pyramids, H) + for ( int i = 0 ; i < size ; i++ ) { + (*pyramids[0]) (i) = (*H) (i); + } + + Array2Df* L = new Array2Df (width, height); + gaussianBlur ( *pyramids[0], *L ); + + for ( int k = 1 ; k < nlevels ; k++ ) { + if (width > 2 && height > 2) { + width /= 2; + height /= 2; + pyramids[k] = new Array2Df (width, height); + downSample (*L, *pyramids[k]); + } else { + // RT - now nlevels is fixed in tmo_fattal02 (see the comment in + // there), so it might happen that we have to add some padding to + // the gaussian pyramids + pyramids[k] = new Array2Df (width, height); + + for (int j = 0, n = width * height; j < n; ++j) { + (*pyramids[k]) (j) = (*L) (j); + } + } + + if (k < nlevels - 1) { + delete L; + L = new Array2Df (width, height); + gaussianBlur ( *pyramids[k], *L ); + } + } + + delete L; +} + +//-------------------------------------------------------------------- + +float calculateGradients (Array2Df* H, Array2Df* G, int k) +{ + const int width = H->getCols(); + const int height = H->getRows(); + const float divider = pow ( 2.0f, k + 1 ); + float avgGrad = 0.0f; + + #pragma omp parallel for reduction(+:avgGrad) + + for ( int y = 0 ; y < height ; y++ ) { + int n = (y == 0 ? 0 : y - 1); + int s = (y + 1 == height ? y : y + 1); + + for ( int x = 0 ; x < width ; x++ ) { + float gx, gy; + int w, e; + w = (x == 0 ? 0 : x - 1); + e = (x + 1 == width ? x : x + 1); + + gx = ((*H) (w, y) - (*H) (e, y)); + + gy = ((*H) (x, s) - (*H) (x, n)); + // note this implicitely assumes that H(-1)=H(0) + // for the fft-pde slover this would need adjustment as H(-1)=H(1) + // is assumed, which means gx=0.0, gy=0.0 at the boundaries + // however, the impact is not visible so we ignore this here + + (*G) (x, y) = sqrt (gx * gx + gy * gy) / divider; + avgGrad += (*G) (x, y); + } + } + + return avgGrad / (width * height); +} + +//-------------------------------------------------------------------- + +void upSample (const Array2Df& A, Array2Df& B) +{ + const int width = B.getCols(); + const int height = B.getRows(); + const int awidth = A.getCols(); + const int aheight = A.getRows(); + + //#pragma omp parallel for shared(A, B) + for ( int y = 0 ; y < height ; y++ ) { + for ( int x = 0 ; x < width ; x++ ) { + int ax = static_cast (x * 0.5f); //x / 2.f; + int ay = static_cast (y * 0.5f); //y / 2.f; + ax = (ax < awidth) ? ax : awidth - 1; + ay = (ay < aheight) ? ay : aheight - 1; + + B (x, y) = A (ax, ay); + } + } + +//--- this code below produces 'use of uninitialized value error' +// int width = A->getCols(); +// int height = A->getRows(); +// int x,y; + +// for( y=0 ; ygetCols(); + int height = gradients[nlevels - 1]->getRows(); + Array2Df** fi = new Array2Df*[nlevels]; + + fi[nlevels - 1] = new Array2Df (width, height); + + if (newfattal) { + //#pragma omp parallel for shared(fi) + for ( int k = 0 ; k < width * height ; k++ ) { + (*fi[nlevels - 1]) (k) = 1.0f; + } + } + + for ( int k = nlevels - 1; k >= 0 ; k-- ) { + width = gradients[k]->getCols(); + height = gradients[k]->getRows(); + + // only apply gradients to levels>=detail_level but at least to the coarsest + if ( k >= detail_level + || k == nlevels - 1 + || newfattal == false) { + //DEBUG_STR << "calculateFiMatrix: apply gradient to level " << k << endl; + #pragma omp parallel for shared(fi,avgGrad) + 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 a = alfa * avgGrad[k]; + + float value = pow ((grad + noise) / a, beta - 1.0f); + + if (newfattal) { + (*fi[k]) (x, y) *= value; + } else { + (*fi[k]) (x, y) = value; + } + } + } + } + + // create next level + if ( k > 1 ) { + width = gradients[k - 1]->getCols(); + height = gradients[k - 1]->getRows(); + fi[k - 1] = new Array2Df (width, height); + } else { + fi[0] = FI; // highest level -> result + } + + if ( k > 0 && newfattal ) { + upSample (*fi[k], *fi[k - 1]); // upsample to next level + gaussianBlur (*fi[k - 1], *fi[k - 1]); + } + } + + for ( int k = 1 ; k < nlevels ; k++ ) { + delete fi[k]; + } + + delete[] fi; +} + +inline +void findMaxMinPercentile (const Array2Df& I, + float minPrct, float& minLum, + float maxPrct, float& maxLum) +{ + assert (minPrct <= maxPrct); + + const int size = I.getRows() * I.getCols(); + const float* data = I.data(); + + // we need to find the (minPrct*size) smallest value and the (maxPrct*size) smallest value in I + // We use a histogram based search for speed and to reduce memory usage + // memory usage of this method is 65536 * sizeof(float) * (t + 1) byte, where t is the number of threads + + // We need one global histogram + LUTu histo (65536, LUT_CLIP_BELOW | LUT_CLIP_ABOVE); + histo.clear(); +#ifdef _OPENMP + #pragma omp parallel +#endif + { + // We need one histogram per thread + LUTu histothr (65536, LUT_CLIP_BELOW | LUT_CLIP_ABOVE); + histothr.clear(); + +#ifdef _OPENMP + #pragma omp for nowait +#endif + + for (int i = 0; i < size; ++i) { + // values are in [0;1] range, so we have to multiply with 65535 to get the histogram index + histothr[ (unsigned int) (65535.f * data[i])]++; + } + +#ifdef _OPENMP + #pragma omp critical +#endif + // add per thread histogram to global histogram + histo += histothr; + } + + int k = 0; + int count = 0; + + // find (minPrct*size) smallest value + while (count < minPrct * size) { + count += histo[k++]; + } + + if (k > 0) { // interpolate + int count_ = count - histo[k - 1]; + float c0 = count - minPrct * size; + float c1 = minPrct * size - count_; + minLum = (c1 * k + c0 * (k - 1)) / ((c0 + c1) * 65535.f); + } else { + minLum = k / 65535.f; + } + + // find (maxPrct*size) smallest value + while (count < maxPrct * size) { + count += histo[k++]; + } + + if (k > 0) { // interpolate + int count_ = count - histo[k - 1]; + float c0 = count - maxPrct * size; + float c1 = maxPrct * size - count_; + maxLum = (c1 * k + c0 * (k - 1)) / ((c0 + c1) * 65535.f); + } else { + maxLum = k / 65535.f; + } + +} + +void solve_pde_fft (Array2Df *F, Array2Df *U, Array2Df *buf, bool multithread); + +void tmo_fattal02 (size_t width, + size_t height, + const Array2Df& Y, + Array2Df& L, + float alfa, + float beta, + float noise, + int detail_level, + bool multithread) +{ +// #ifdef TIMER_PROFILING +// msec_timer stop_watch; +// stop_watch.start(); +// #endif + static const float black_point = 0.1f; + static const float white_point = 0.5f; + static const float gamma = 1.0f; // 0.8f; + + // static const int detail_level = 3; + if ( detail_level < 0 ) { + detail_level = 0; + } + + if ( detail_level > 3 ) { + detail_level = 3; + } + + // ph.setValue(2); + // if (ph.canceled()) return; + + /* RT -- we use a hardcoded value for nlevels, to limit the + * dependency of the result on the image size. When using an auto computed + * nlevels value, you would get vastly different results with different + * image sizes, making it essentially impossible to preview the tool + * inside RT. With a hardcoded value, the results for the preview are much + * closer to those for the final image */ + // int MSIZE = 32; // minimum size of gaussian pyramid + // // I believe a smaller value than 32 results in slightly better overall + // // quality but I'm only applying this if the newly implemented fft solver + // // is used in order not to change behaviour of the old version + // // TODO: best let the user decide this value + // // if (fftsolver) + // { + // MSIZE = 8; + // } + + + int size = width * height; + + // find max value, normalize to range 0..100 and take logarithm + float minLum = Y (0, 0); + float maxLum = Y (0, 0); + + #pragma omp parallel for reduction(max:maxLum) + + for ( int i = 0 ; i < size ; i++ ) { + maxLum = std::max (maxLum, Y (i)); + } + + Array2Df* H = new Array2Df (width, height); + float temp = 100.f / maxLum; + float eps = 1e-4f; + #pragma omp parallel + { +#ifdef __SSE2__ + vfloat epsv = F2V (eps); + vfloat tempv = F2V (temp); +#endif + #pragma omp for schedule(dynamic,16) + + for (size_t i = 0 ; i < height ; ++i) { + size_t j = 0; +#ifdef __SSE2__ + + for (; j < width - 3; j += 4) { + STVFU ((*H)[i][j], xlogf (tempv * LVFU (Y[i][j]) + epsv)); + } + +#endif + + for (; j < width; ++j) { + (*H)[i][j] = xlogf (temp * Y[i][j] + eps); + } + } + } + + /** RT - this is also here to reduce the dependency of the results on the + * input image size, with the primary aim of having a preview in RT that is + * reasonably close to the actual output image. Intuitively, what we do is + * to put a cap on the dimension of the image processed, so that it is close + * in size to the typical preview that you will see on a normal consumer + * monitor. (That's where the 1920 value for RT_dimension_cap comes from.) + * However, we can't simply downscale the input Y array and then upscale it + * on output, because that would cause a big loss of sharpness (confirmed by + * testing). + * So, we use a different method: we downscale the H array, so that we + * compute a downscaled gaussian pyramid and a downscaled FI matrix. Then, + * we upscale the FI matrix later on, before it gets combined with the + * original input luminance array H. This seems to preserve the input + * sharpness and at the same time significantly reduce the dependency of the + * result on the input size. Clearly this is a hack, and keep in mind that I + * do not really know how Fattal works (it comes from LuminanceHDR almost + * verbatim), so this should probably be revised/reviewed by someone who + * knows better... also, we use a quite naive bilinear interpolation + * algorithm (see rescale_bilinear below), which could definitely be + * improved */ + int fullwidth = width; + int fullheight = height; + int dim = std::max (width, height); + Array2Df *fullH = nullptr; + + if (dim > RT_dimension_cap) { + float s = float (RT_dimension_cap) / float (dim); + Array2Df *HH = new Array2Df (width * s, height * s); + rescale_bilinear (*H, *HH, multithread); + fullH = H; + H = HH; + width = H->getCols(); + height = H->getRows(); + } + + /** RT */ + + // create gaussian pyramids + // int mins = (width= MSIZE ) + // { + // nlevels++; + // mins /= 2; + // } + // // std::cout << "DEBUG: nlevels = " << nlevels << ", mins = " << mins << std::endl; + // // The following lines solves a bug with images particularly small + // if (nlevels == 0) nlevels = 1; + const int nlevels = 7; // RT -- see above + + Array2Df** pyramids = new Array2Df*[nlevels]; + createGaussianPyramids (H, pyramids, nlevels); + // ph.setValue(8); + + // calculate gradients and its average values on pyramid levels + Array2Df** gradients = new Array2Df*[nlevels]; + float* avgGrad = new float[nlevels]; + + for ( int k = 0 ; k < nlevels ; k++ ) { + gradients[k] = new Array2Df (pyramids[k]->getCols(), pyramids[k]->getRows()); + avgGrad[k] = calculateGradients (pyramids[k], gradients[k], k); + delete pyramids[k]; + } + + delete[] pyramids; + // ph.setValue(12); + + // calculate fi matrix + Array2Df* FI = new Array2Df (width, height); + calculateFiMatrix (FI, gradients, avgGrad, nlevels, detail_level, alfa, beta, noise); + +// dumpPFS( "FI.pfs", FI, "Y" ); + for ( int i = 0 ; i < nlevels ; i++ ) { + delete gradients[i]; + } + + delete[] gradients; + delete[] avgGrad; + // ph.setValue(16); + // if (ph.canceled()){ + // delete FI; + // delete H; + // return; + // } + + /** - RT - bring back the FI image to the input size if it was downscaled */ + if (fullH) { + Array2Df *FI2 = new Array2Df (fullwidth, fullheight); + rescale_bilinear (*FI, *FI2, multithread); + delete FI; + FI = FI2; + width = fullwidth; + height = fullheight; + delete H; + H = fullH; + } + + /** RT */ + + // attenuate gradients + Array2Df* Gx = new Array2Df (width, height); + Array2Df* Gy = new Array2Df (width, height); + + // the fft solver solves the Poisson pde but with slightly different + // boundary conditions, so we need to adjust the assembly of the right hand + // side accordingly (basically fft solver assumes U(-1) = U(1), whereas zero + // Neumann conditions assume U(-1)=U(0)), see also divergence calculation + // if (fftsolver) + #pragma omp parallel for + + for ( size_t y = 0 ; y < height ; y++ ) { + // sets index+1 based on the boundary assumption H(N+1)=H(N-1) + unsigned int yp1 = (y + 1 >= height ? height - 2 : y + 1); + + for ( size_t x = 0 ; x < width ; x++ ) { + // 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)); + } + } + + delete H; + + // calculate divergence + #pragma omp parallel for + + for ( size_t y = 0; y < height; ++y ) { + for ( size_t x = 0; x < width; ++x ) { + (*FI) (x, y) = (*Gx) (x, y) + (*Gy) (x, y); + + if ( x > 0 ) { + (*FI) (x, y) -= (*Gx) (x - 1, y); + } + + if ( y > 0 ) { + (*FI) (x, y) -= (*Gy) (x, y - 1); + } + + // if (fftsolver) + { + if (x == 0) { + (*FI) (x, y) += (*Gx) (x, y); + } + + if (y == 0) { + (*FI) (x, y) += (*Gy) (x, y); + } + } + + } + } + + //delete Gx; // RT - reused as temp buffer in solve_pde_fft, deleted later + delete Gy; + + // solve pde and exponentiate (ie recover compressed image) + { + // if (fftsolver) + { + MyMutex::MyLock lock (*fftwMutex); + solve_pde_fft (FI, &L, Gx, multithread); //, ph); + } + delete Gx; + delete FI; + // else + // { + // solve_pde_multigrid(&DivG, &U, ph); + // } +// #ifndef NDEBUG +// printf("\npde residual error: %f\n", residual_pde(&U, &DivG)); +// #endif + // ph.setValue(90); + // if ( ph.canceled() ) + // { + // return; + // } + #pragma omp parallel + { +#ifdef __SSE2__ + vfloat gammav = F2V (gamma); +#endif + #pragma omp for schedule(dynamic,16) + + for (size_t i = 0 ; i < height ; i++) { + size_t j = 0; +#ifdef __SSE2__ + + for (; j < width - 3; j += 4) { + STVFU (L[i][j], xexpf (gammav * LVFU (L[i][j]))); + } + +#endif + + for (; j < width; j++) { + L[i][j] = xexpf ( gamma * L[i][j]); + } + } + } + } + // ph.setValue(95); + + // remove percentile of min and max values and renormalize + float cut_min = 0.01f * black_point; + float cut_max = 1.0f - 0.01f * white_point; + assert (cut_min >= 0.0f && (cut_max <= 1.0f) && (cut_min < cut_max)); + findMaxMinPercentile (L, cut_min, minLum, cut_max, maxLum); + float dividor = (maxLum - minLum); + + #pragma omp parallel for + + for (size_t i = 0; i < height; ++i) { + for (size_t j = 0; j < width; ++j) { + L[i][j] = std::max ((L[i][j] - minLum) / dividor, 0.f); + // note, we intentionally do not cut off values > 1.0 + } + } +} + + +/** + * + * @file pde_fft.cpp + * @brief Direct Poisson solver using the discrete cosine transform + * + * @author Tino Kluge (tino.kluge@hrz.tu-chemnitz.de) + * + */ + +////////////////////////////////////////////////////////////////////// +// Direct Poisson solver using the discrete cosine transform +////////////////////////////////////////////////////////////////////// +// by Tino Kluge (tino.kluge@hrz.tu-chemnitz.de) +// +// let U and F be matrices of order (n1,n2), ie n1=height, n2=width +// and L_x of order (n2,n2) and L_y of order (n1,n1) and both +// representing the 1d Laplace operator with Neumann boundary conditions, +// ie L_x and L_y are tridiagonal matrices of the form +// +// ( -2 2 ) +// ( 1 -2 1 ) +// ( . . . ) +// ( 1 -2 1 ) +// ( 2 -2 ) +// +// then this solver computes U given F based on the equation +// +// ------------------------- +// L_y U + (L_x U^tr)^tr = F +// ------------------------- +// +// Note, if the first and last row of L_x and L_y contained one's instead of +// two's then this equation would be exactly the 2d Poisson equation with +// Neumann boundary conditions. As a simple rule: +// - Neumann: assume U(-1)=U(0) --> U(i-1) - 2 U(i) + U(i+1) becomes +// i=0: U(0) - 2 U(0) + U(1) = -U(0) + U(1) +// - our system: assume U(-1)=U(1) --> this becomes +// i=0: U(1) - 2(0) + U(1) = -2 U(0) + 2 U(1) +// +// The multi grid solver solve_pde_multigrid() solves the 2d Poisson pde +// with the right Neumann boundary conditions, U(-1)=U(0), see function +// atimes(). This means the assembly of the right hand side F is different +// for both solvers. + +// #include + +// #include + +// #include +// #include +// #include "arch/math.h" +// #include +// #ifdef _OPENMP +// #include +// #endif +// #include +// #include + +// #include "Libpfs/progress.h" +// #include "Libpfs/array2d.h" +// #include "pde.h" + +// using namespace std; + + +// #ifndef SQR +// #define SQR(x) (x)*(x) +// #endif + + +// returns T = EVy A EVx^tr +// note, modifies input data +void transform_ev2normal (Array2Df *A, Array2Df *T) +{ + int width = A->getCols(); + int height = A->getRows(); + assert ((int)T->getCols() == width && (int)T->getRows() == height); + + // the discrete cosine transform is not exactly the transform needed + // need to scale input values to get the right transformation + #pragma omp parallel for + + for (int y = 1 ; y < height - 1 ; y++ ) + for (int x = 1 ; x < width - 1 ; x++ ) { + (*A) (x, y) *= 0.25f; + } + + for (int x = 1 ; x < width - 1 ; x++ ) { + (*A) (x, 0) *= 0.5f; + (*A) (x, height - 1) *= 0.5f; + } + + for (int y = 1 ; y < height - 1 ; y++ ) { + (*A) (0, y) *= 0.5; + (*A) (width - 1, y) *= 0.5f; + } + + // note, fftw provides its own memory allocation routines which + // ensure that memory is properly 16/32 byte aligned so it can + // use SSE/AVX operations (2/4 double ops in parallel), if our + // data is not properly aligned fftw won't use SSE/AVX + // (I believe new() aligns memory to 16 byte so avoid overhead here) + // + // double* in = (double*) fftwf_malloc(sizeof(double) * width*height); + // fftwf_free(in); + + // executes 2d discrete cosine transform + fftwf_plan p; + p = fftwf_plan_r2r_2d (height, width, A->data(), T->data(), + FFTW_REDFT00, FFTW_REDFT00, FFTW_ESTIMATE); + fftwf_execute (p); + fftwf_destroy_plan (p); +} + + +// returns T = EVy^-1 * A * (EVx^-1)^tr +void transform_normal2ev (Array2Df *A, Array2Df *T) +{ + int width = A->getCols(); + int height = A->getRows(); + assert ((int)T->getCols() == width && (int)T->getRows() == height); + + // executes 2d discrete cosine transform + fftwf_plan p; + p = fftwf_plan_r2r_2d (height, width, A->data(), T->data(), + FFTW_REDFT00, FFTW_REDFT00, FFTW_ESTIMATE); + fftwf_execute (p); + fftwf_destroy_plan (p); + + // need to scale the output matrix to get the right transform + float factor = (1.0f / ((height - 1) * (width - 1))); + #pragma omp parallel for + + for (int y = 0 ; y < height ; y++ ) + for (int x = 0 ; x < width ; x++ ) { + (*T) (x, y) *= factor; + } + + for (int x = 0 ; x < width ; x++ ) { + (*T) (x, 0) *= 0.5f; + (*T) (x, height - 1) *= 0.5f; + } + + for (int y = 0 ; y < height ; y++ ) { + (*T) (0, y) *= 0.5f; + (*T) (width - 1, y) *= 0.5f; + } +} + +// returns the eigenvalues of the 1d laplace operator +std::vector get_lambda (int n) +{ + assert (n > 1); + std::vector v (n); + + for (int i = 0; i < n; i++) { + v[i] = -4.0 * SQR (sin ((double)i / (2 * (n - 1)) * RT_PI)); + } + + return v; +} + +// // makes boundary conditions compatible so that a solution exists +// void make_compatible_boundary(Array2Df *F) +// { +// int width = F->getCols(); +// int height = F->getRows(); + +// double sum=0.0; +// for(int y=1 ; ygetCols(); + int height = F->getRows(); + assert ((int)U->getCols() == width && (int)U->getRows() == height); + assert (buf->getCols() == width && buf->getRows() == height); + + // activate parallel execution of fft routines +#ifdef RT_FFTW3F_OMP + + if (multithread) { + fftwf_init_threads(); + fftwf_plan_with_nthreads ( omp_get_max_threads() ); + } + +// #else +// fftwf_plan_with_nthreads( 2 ); +#endif + + // in general there might not be a solution to the Poisson pde + // with Neumann boundary conditions unless the boundary satisfies + // an integral condition, this function modifies the boundary so that + // the condition is exactly satisfied + // if(adjust_bound) + // { + // //DEBUG_STR << "solve_pde_fft: checking boundary conditions" << std::endl; + // make_compatible_boundary(F); + // } + + // transforms F into eigenvector space: Ftr = + //DEBUG_STR << "solve_pde_fft: transform F to ev space (fft)" << std::endl; + Array2Df* F_tr = buf; //new Array2Df(width,height); + transform_normal2ev (F, F_tr); + // TODO: F no longer needed so could release memory, but as it is an + // input parameter we won't do that + // ph.setValue(50); + // if (ph.canceled()) + // { + // delete F_tr; + // return; + // } + + //DEBUG_STR << "solve_pde_fft: F_tr(0,0) = " << (*F_tr)(0,0); + //DEBUG_STR << " (must be 0 for solution to exist)" << std::endl; + + // in the eigenvector space the solution is very simple + //DEBUG_STR << "solve_pde_fft: solve in eigenvector space" << std::endl; +// Array2Df* U_tr = new Array2Df(width,height); + std::vector l1 = get_lambda (height); + std::vector l2 = get_lambda (width); + + #pragma omp parallel for + + 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) (0, 0) = 0.f; // any value ok, only adds a const to the solution + + // transforms U_tr back to the normal space + //DEBUG_STR << "solve_pde_fft: transform U_tr to normal space (fft)" << std::endl; + transform_ev2normal (F_tr, U); +// delete F_tr; // no longer needed so release memory + + // the solution U as calculated will satisfy something like int U = 0 + // since for any constant c, U-c is also a solution and we are mainly + // working in the logspace of (0,1) data we prefer to have + // a solution which has no positive values: U_new(x,y)=U(x,y)-max + // (not really needed but good for numerics as we later take exp(U)) + //DEBUG_STR << "solve_pde_fft: removing constant from solution" << std::endl; + float max = 0.f; + #pragma omp parallel for reduction(max:max) + + for (int i = 0; i < width * height; i++) { + max = std::max (max, (*U) (i)); + } + + #pragma omp parallel for + + for (int i = 0; i < width * height; i++) { + (*U) (i) -= max; + } + + // fft parallel threads cleanup, better handled outside this function? +#ifdef RT_FFTW3F_OMP + + if (multithread) { + fftwf_cleanup_threads(); + } + +#endif + + // ph.setValue(90); + //DEBUG_STR << "solve_pde_fft: done" << std::endl; +} + + +// --------------------------------------------------------------------- +// the functions below are only for test purposes to check the accuracy +// of the pde solvers + + +// // returns the norm of (Laplace U - F) of all interior points +// // useful to compare solvers +// float residual_pde(Array2Df* U, Array2Df* F) +// { +// int width = U->getCols(); +// int height = U->getRows(); +// assert((int)F->getCols()==width && (int)F->getRows()==height); + +// double res=0.0; +// for(int y=1;y( sqrt(res) ); +// } + + +/***************************************************************************** + * RT code from here on + *****************************************************************************/ + +inline float get_bilinear_value (const Array2Df &src, float x, float y) +{ + // Get integer and fractional parts of numbers + int xi = x; + int yi = y; + float xf = x - xi; + float yf = y - yi; + int xi1 = std::min (xi + 1, src.getCols() - 1); + int yi1 = std::min (yi + 1, src.getRows() - 1); + + float bl = src (xi, yi); + float br = src (xi1, yi); + float tl = src (xi, yi1); + float tr = src (xi1, yi1); + + // interpolate + float b = xf * br + (1.f - xf) * bl; + float t = xf * tr + (1.f - xf) * tl; + float pxf = yf * t + (1.f - yf) * b; + return pxf; +} + + +void rescale_bilinear (const Array2Df &src, Array2Df &dst, bool multithread) +{ + float col_scale = float (src.getCols()) / float (dst.getCols()); + float row_scale = float (src.getRows()) / float (dst.getRows()); + +#ifdef _OPENMP + #pragma omp parallel for if (multithread) +#endif + + for (int y = 0; y < dst.getRows(); ++y) { + float ymrs = y * row_scale; + + for (int x = 0; x < dst.getCols(); ++x) { + dst (x, y) = get_bilinear_value (src, x * col_scale, ymrs); + } + } +} + +void rescale_nearest (const Array2Df &src, Array2Df &dst, bool multithread) +{ + const int width = src.getCols(); + const int height = src.getRows(); + const int nw = dst.getCols(); + const int nh = dst.getRows(); + +#ifdef _OPENMP + #pragma omp parallel for if (multithread) +#endif + + for (int y = 0; y < nh; ++y) { + int sy = y * height / nh; + + for (int x = 0; x < nw; ++x) { + int sx = x * width / nw; + dst (x, y) = src (sx, sy); + } + } +} + + +inline float luminance (float r, float g, float b, TMatrix ws) +{ + return r * ws[1][0] + g * ws[1][1] + b * ws[1][2]; +} + + +inline int round_up_pow2 (int dim) +{ + // from https://graphics.stanford.edu/~seander/bithacks.html + assert (dim > 0); + unsigned int v = dim; + v--; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + v++; + return v; +} + +inline int find_fast_dim (int dim) +{ + // as per the FFTW docs: + // + // FFTW is generally best at handling sizes of the form 2a 3b 5c 7d 11e + // 13f, where e+f is either 0 or 1. + // + // Here, we try to round up to the nearest dim that can be expressed in + // the above form. This is not exhaustive, but should be ok for pictures + // up to 100MPix at least + + int d1 = round_up_pow2 (dim); + std::vector d = { + d1 / 128 * 65, + d1 / 64 * 33, + d1 / 512 * 273, + d1 / 16 * 9, + d1 / 8 * 5, + d1 / 16 * 11, + d1 / 128 * 91, + d1 / 4 * 3, + d1 / 64 * 49, + d1 / 16 * 13, + d1 / 8 * 7, + d1 + }; + + for (size_t i = 0; i < d.size(); ++i) { + if (d[i] >= dim) { + return d[i]; + } + } + + assert (false); + return dim; +} + +} // namespace + + +void ImProcFunctions::ToneMapFattal02 (Imagefloat *rgb) +{ + BENCHFUN + const int detail_level = 3; + + float alpha = 1.f; + + if (params->fattal.threshold < 0) { + alpha += (params->fattal.threshold * 0.9f) / 100.f; + } else if (params->fattal.threshold > 0) { + alpha += params->fattal.threshold / 100.f; + } + + float beta = 1.f - (params->fattal.amount * 0.3f) / 100.f; + + // sanity check + if (alpha <= 0 || beta <= 0) { + return; + } + + int w = rgb->getWidth(); + int h = rgb->getHeight(); + + Array2Df Yr (w, h); + + const float epsilon = 1e-4f; + const float luminance_noise_floor = 65.535f; + const float min_luminance = 1.f; + TMatrix ws = ICCStore::getInstance()->workingSpaceMatrix (params->icm.working); + +#ifdef _OPENMP + #pragma omp parallel for if (multiThread) +#endif + + for (int y = 0; y < h; y++) { + for (int x = 0; x < w; x++) { + Yr (x, y) = std::max (luminance (rgb->r (y, x), rgb->g (y, x), rgb->b (y, x), ws), min_luminance); // clip really black pixels + } + } + + // median filter on the deep shadows, to avoid boosting noise + // because w2 >= w and h2 >= h, we can use the L buffer as temporary buffer for Median_Denoise() + int w2 = find_fast_dim (w) + 1; + int h2 = find_fast_dim (h) + 1; + Array2Df L (w2, h2); + { +#ifdef _OPENMP + int num_threads = multiThread ? omp_get_max_threads() : 1; +#else + int num_threads = 1; +#endif + float r = float (std::max (w, h)) / float (RT_dimension_cap); + Median med; + + if (r >= 3) { + med = Median::TYPE_7X7; + } else if (r >= 2) { + med = Median::TYPE_5X5_STRONG; + } else if (r >= 1) { + med = Median::TYPE_5X5_SOFT; + } else { + med = Median::TYPE_3X3_STRONG; + } + + Median_Denoise (Yr, Yr, luminance_noise_floor, w, h, med, 1, num_threads, L); + } + + float noise = alpha * 0.01f; + + if (settings->verbose) { + std::cout << "ToneMapFattal02: alpha = " << alpha << ", beta = " << beta + << ", detail_level = " << detail_level << std::endl; + } + + rescale_nearest (Yr, L, multiThread); + tmo_fattal02 (w2, h2, L, L, alpha, beta, noise, detail_level, multiThread); + +// tmo_fattal02(w, h, Yr, L, alpha, beta, noise, detail_level, multiThread); + +#ifdef _OPENMP + #pragma omp parallel for if(multiThread) +#endif + + for (int y = 0; y < h; y++) { + int yy = y * h2 / h; + + for (int x = 0; x < w; x++) { + int xx = x * w2 / w; + float Y = Yr (x, y); + float l = std::max (L (xx, yy), epsilon) * (65535.f / Y); + rgb->r (y, x) = std::max (rgb->r (y, x), 0.f) * l; + rgb->g (y, x) = std::max (rgb->g (y, x), 0.f) * l; + rgb->b (y, x) = std::max (rgb->b (y, x), 0.f) * l; + + assert (std::isfinite (rgb->r (y, x))); + assert (std::isfinite (rgb->g (y, x))); + assert (std::isfinite (rgb->b (y, x))); + } + } +} + + +} // namespace rtengine diff --git a/rtexif/CMakeLists.txt b/rtexif/CMakeLists.txt index 820f682a4..9747b03fb 100644 --- a/rtexif/CMakeLists.txt +++ b/rtexif/CMakeLists.txt @@ -3,11 +3,11 @@ add_dependencies(rtexif UpdateInfo) if(WIN32) include_directories(${EXTRA_INCDIR} ${GLIB2_INCLUDE_DIRS} ${GLIBMM_INCLUDE_DIRS} ${GTK_INCLUDE_DIRS} ${GTKMM_INCLUDE_DIRS}) - link_directories(. "${PROJECT_SOURCE_DIR}/rtexif" ${EXTRA_LIBDIR} ${GLIB2_LIBRARY_DIRS} ${GLIBMM_LIBRARY_DIRS} ${GTK_LIBRARY_DIRS} ${GTKMM_LIBRARY_DIRS}) + 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}) + 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}") diff --git a/rtexif/canonattribs.cc b/rtexif/canonattribs.cc index 01b00dd53..c1ab6f4f2 100644 --- a/rtexif/canonattribs.cc +++ b/rtexif/canonattribs.cc @@ -650,8 +650,11 @@ public: choices.insert (p_t (53, "Canon EF-S 18-55mm f/3.5-5.6 III")); choices.insert (p_t (54, "Canon EF-S 55-250mm f/4-5.6 IS II")); choices.insert (p_t (60, "Irix 11mm f/4")); + choices.insert (p_t (80, "Canon TS-E 50mm f/2.8L Macro")); + choices.insert (p_t (81, "Canon TS-E 90mm f/2.8L Macro")); + choices.insert (p_t (82, "Canon TS-E 135mm f/4L Macro")); choices.insert (p_t (94, "Canon TS-E 17mm f/4L")); - choices.insert (p_t (95, "Canon TS-E 24.0mm f/3.5 L II")); + choices.insert (p_t (95, "Canon TS-E 24mm f/3.5L II")); choices.insert (p_t (124, "Canon MP-E 65mm f/2.8 1-5x Macro Photo")); choices.insert (p_t (125, "Canon TS-E 24mm f/3.5L")); choices.insert (p_t (126, "Canon TS-E 45mm f/2.8")); @@ -785,6 +788,7 @@ public: choices.insert (p_t (183, "Sigma 180mm f/2.8 EX DG OS HSM APO Macro")); choices.insert (p_t (183, "Sigma 150-600mm f/5-6.3 DG OS HSM | C")); choices.insert (p_t (183, "Sigma 150-600mm f/5-6.3 DG OS HSM | S")); + choices.insert (p_t (183, "Sigma 100-400mm f/5-6.3 DG OS HSM")); choices.insert (p_t (184, "Canon EF 400mm f/2.8L + 2x")); choices.insert (p_t (185, "Canon EF 600mm f/4L IS")); choices.insert (p_t (186, "Canon EF 70-200mm f/4L")); @@ -797,7 +801,8 @@ public: choices.insert (p_t (194, "Canon EF 80-200mm f/4.5-5.6 USM")); choices.insert (p_t (195, "Canon EF 35-105mm f/4.5-5.6 USM")); choices.insert (p_t (196, "Canon EF 75-300mm f/4-5.6 USM")); - choices.insert (p_t (197, "Canon EF 75-300mm f/4-5.6 IS USM")); + choices.insert (p_t (197, "Canon EF 75-300mm f/4-5.6 IS USM or Sigma Lens")); + choices.insert (p_t (197, "Sigma 18-300mm f/3.5-6.3 DC Macro OS HS")); choices.insert (p_t (198, "Canon EF 50mm f/1.4 USM or Zeiss Lens")); choices.insert (p_t (198, "Zeiss Otus 55mm f/1.4 ZE")); choices.insert (p_t (198, "Zeiss Otus 85mm f/1.4 ZE")); @@ -859,11 +864,13 @@ public: choices.insert (p_t (490, "Canon EF 8-15mm f/4L Fisheye USM")); choices.insert (p_t (491, "Canon EF 300mm f/2.8L IS II USM or Tamron Lens")); choices.insert (p_t (491, "Tamron SP 70-200mm f/2.8 Di VC USD G2 (A025)")); + choices.insert (p_t (491, "Tamron 18-400mm f/3.5-6.3 Di II VC HLD (B028)")); choices.insert (p_t (492, "Canon EF 400mm f/2.8L IS II USM")); choices.insert (p_t (493, "Canon EF 500mm f/4L IS II USM or EF 24-105mm f4L IS USM")); choices.insert (p_t (493, "Canon EF 24-105mm f/4L IS USM")); choices.insert (p_t (494, "Canon EF 600mm f/4.0L IS II USM")); - choices.insert (p_t (495, "Canon EF 24-70mm f/2.8L II USM")); + choices.insert (p_t (495, "Canon EF 24-70mm f/2.8L II USM or Sigma Lens")); + choices.insert (p_t (495, "Sigma 24-70mm F2.8 DG OS HSM | A")); choices.insert (p_t (496, "Canon EF 200-400mm f/4L IS USM")); choices.insert (p_t (499, "Canon EF 200-400mm f/4L IS USM + 1.4x")); choices.insert (p_t (502, "Canon EF 28mm f/2.8 IS USM")); @@ -872,7 +879,8 @@ public: choices.insert (p_t (505, "Canon EF 35mm f/2 IS USM")); choices.insert (p_t (506, "Canon EF 400mm f/4 DO IS II USM")); choices.insert (p_t (507, "Canon EF 16-35mm f/4L IS USM")); - choices.insert (p_t (508, "Canon EF 11-24mm f/4L USM")); + choices.insert (p_t (508, "Canon EF 11-24mm f/4L USM or Tamron Lens")); + choices.insert (p_t (508, "Tamron 10-24mm f/3.5-4.5 Di II VC HLD")); choices.insert (p_t (747, "Canon EF 100-400mm f/4.5-5.6L IS II USM or Tamron Lens")); choices.insert (p_t (747, "Tamron SP 150-600mm F5-6.3 Di VC USD G2")); choices.insert (p_t (748, "Canon EF 100-400mm f/4.5-5.6L IS II USM + 1.4x")); @@ -896,8 +904,14 @@ public: choices.insert (p_t (4156, "Canon EF 50mm f/1.8 STM")); choices.insert (p_t (4157, "Canon EF-M 18-150mm 1:3.5-6.3 IS STM")); choices.insert (p_t (4158, "Canon EF-S 18-55mm f/4-5.6 IS STM")); + choices.insert (p_t (4160, "Canon EF-S 35mm f/2.8 Macro IS STM")); choices.insert (p_t (36910, "Canon EF 70-300mm f/4-5.6 IS II USM")); choices.insert (p_t (36912, "Canon EF-S 18-135mm f/3.5-5.6 IS USM")); + choices.insert (p_t (61491, "Canon CN-E 14mm T3.1 L F")); + choices.insert (p_t (61492, "Canon CN-E 24mm T1.5 L F")); + choices.insert (p_t (61494, "Canon CN-E 85mm T1.3 L F")); + choices.insert (p_t (61495, "Canon CN-E 135mm T2.2 L F")); + choices.insert (p_t (61496, "Canon CN-E 35mm T1.5 L F")); choices.insert (p_t (65535, "n/a")); } @@ -1102,7 +1116,7 @@ public: sprintf (buffer, "%d", a); return buffer; } - virtual double toDouble (Tag* t, int ofs) + virtual double toDouble (const Tag* t, int ofs) { int a = Interpreter::toInt (t, ofs); @@ -1113,7 +1127,7 @@ public: return 0.; } } - virtual int toInt (Tag* t, int ofs, TagType astype) + virtual int toInt (const Tag* t, int ofs, TagType astype) { int a = Interpreter::toInt (t, ofs, astype); @@ -1577,7 +1591,7 @@ public: choices[41353216] = "PowerShot SD940 IS / Digital IXUS 120 IS / IXY Digital 220 IS"; choices[41943040] = "PowerShot A495"; choices[42008576] = "PowerShot A490"; - choices[42074112] = "PowerShot A3100 IS / A3150 IS"; + choices[42074112] = "PowerShot A3100/A3150 IS"; choices[42139648] = "PowerShot A3000 IS"; choices[42205184] = "PowerShot SD1400 IS / IXUS 130 / IXY 400F"; choices[42270720] = "PowerShot SD1300 IS / IXUS 105 / IXY 200F"; @@ -1621,7 +1635,7 @@ public: choices[52887552] = "PowerShot A2400 IS"; choices[52953088] = "PowerShot A2300"; choices[53673984] = "PowerShot G15"; - choices[53739520] = "PowerShot SX50"; + choices[53739520] = "PowerShot SX50 HS"; choices[53805056] = "PowerShot SX160 IS"; choices[53870592] = "PowerShot S110 (new)"; choices[53936128] = "PowerShot SX500 IS"; @@ -1631,6 +1645,7 @@ public: choices[54591488] = "PowerShot SX270 HS"; choices[54657024] = "PowerShot A3500 IS"; choices[54722560] = "PowerShot A2600"; + choices[54788096] = "PowerShot SX275 HS"; choices[54853632] = "PowerShot A1400"; choices[54919168] = "PowerShot ELPH 130 IS / IXUS 140 / IXY 110F"; choices[54984704] = "PowerShot ELPH 115/120 IS / IXUS 132/135 / IXY 90F/100F"; @@ -1671,6 +1686,7 @@ public: choices[60030976] = "EOS M5"; choices[60096512] = "PowerShot G5 X"; choices[60227584] = "PowerShot G7 X Mark II"; + choices[60293120] = "EOS M100"; choices[60358656] = "PowerShot ELPH 360 HS / IXUS 285 HS / IXY 650"; choices[67174400] = "PowerShot SX540 HS"; choices[67239936] = "PowerShot SX420 IS"; @@ -1679,6 +1695,11 @@ public: choices[67371009] = "IXY 180"; choices[67436544] = "PowerShot SX720 HS"; choices[67502080] = "PowerShot SX620 HS"; + choices[67567616] = "EOS M6"; + choices[68157440] = "PowerShot G9 X Mark II"; + choices[68485120] = "PowerShot ELPH 185 / IXUS 185 / IXY 200"; + choices[68550656] = "PowerShot SX430 IS"; + choices[68616192] = "PowerShot SX730 HS"; choices[100925440] = "PowerShot S100 / Digital IXUS / IXY Digital"; choices[1074255475] = "DC19/DC21/DC22"; choices[1074255476] = "XH A1"; @@ -1708,6 +1729,7 @@ public: choices[1074256527] = "HF M30/M31/M36/M300/M306"; choices[1074256528] = "HF S20/S21/S200"; choices[1074256530] = "FS31/FS36/FS37/FS300/FS305/FS306/FS307"; + choices[1074257056] = "EOS C300"; choices[1074257321] = "HF G25"; choices[1074257844] = "XC10"; choices[2147483649] = "EOS-1D"; @@ -1763,6 +1785,10 @@ public: choices[2147484563] = "EOS Rebel T6i / 750D / Kiss X8i"; choices[2147484673] = "EOS 5DS R"; choices[2147484676] = "EOS Rebel T6 / 1300D / Kiss X80"; + choices[2147484677] = "EOS Rebel T7i / 800D / Kiss X9i"; + choices[2147484678] = "EOS 6D Mark II"; + choices[2147484680] = "EOS 77D / 9000D"; + choices[2147484695] = "EOS Rebel SL2 / 200D / Kiss X9"; } }; CAModelIDInterpreter caModelIDInterpreter; diff --git a/rtexif/nikonattribs.cc b/rtexif/nikonattribs.cc index bf4fc5a6b..cfdf61edb 100644 --- a/rtexif/nikonattribs.cc +++ b/rtexif/nikonattribs.cc @@ -55,7 +55,7 @@ public: sprintf (buffer, "%d", a); return buffer; } - virtual double toDouble (Tag* t, int ofs) + virtual double toDouble (const Tag* t, int ofs) { int a = t->getValue()[ofs]; @@ -66,7 +66,7 @@ public: return 0.; } } - virtual int toInt (Tag* t, int ofs, TagType astype) + virtual int toInt (const Tag* t, int ofs, TagType astype) { int a = t->getValue()[ofs]; @@ -557,8 +557,10 @@ public: }; NALensDataInterpreter naLensDataInterpreter; const std::map NALensDataInterpreter::lenses = { - // The key is a composite string made of 8 HEX bytes - // LensIDNumber LensFStops MinFocalLength MaxFocalLength MaxApertureAtMinFocal MaxApertureAtMaxFocal MCUVersion and LensType + /* + * The Nikon LensID is constructed as a Composite tag from the raw hex values of 8 other tags: + * LensIDNumber, LensFStops, MinFocalLength, MaxFocalLength, MaxApertureAtMinFocal, MaxApertureAtMaxFocal, MCUVersion and LensType, in that order. + */ {"00 00 00 00 00 00 00 01", "Manual Lens No CPU"}, {"00 00 00 00 00 00 E1 12", "TC-17E II"}, {"00 00 00 00 00 00 F1 0C", "TC-14E [II] or Sigma APO Tele Converter 1.4x EX DG or Kenko Teleplus PRO 300 DG 1.4x"}, @@ -680,6 +682,7 @@ const std::map NALensDataInterpreter::lenses = { {"10 3D 3C 60 2C 3C D2 02", "Tamron AF 28-80mm f/3.5-5.6 Aspherical (177D)"}, {"10 48 8E 8E 30 30 08 00", "AF Nikkor 300mm f/4 IF-ED"}, {"11 48 44 5C 24 24 08 00", "AF Zoom-Nikkor 35-70mm f/2.8"}, + {"11 48 44 5C 24 24 15 00", "AF Zoom-Nikkor 35-70mm f/2.8"}, {"12 36 5C 81 35 3D 09 00", "Cosina AF Zoom 70-210mm f/4.5-5.6 MC Macro"}, {"12 36 69 97 35 42 09 00", "Soligor AF Zoom 100-400mm 1:4.5-6.7 MC"}, {"12 38 69 97 35 42 09 02", "Promaster Spectrum 7 100-400mm f/4.5-6.7"}, @@ -952,6 +955,7 @@ const std::map NALensDataInterpreter::lenses = { {"92 48 24 37 24 24 94 06", "AF-S Zoom-Nikkor 14-24mm f/2.8G ED"}, {"93 48 37 5C 24 24 95 06", "AF-S Zoom-Nikkor 24-70mm f/2.8G ED"}, {"94 40 2D 53 2C 3C 96 06", "AF-S DX Zoom-Nikkor 18-55mm f/3.5-5.6G ED II"}, + {"94 48 7C 7C 24 24 4B 0E", "Sigma 180mm f/2.8 APO Macro EX DG OS"}, {"95 00 37 37 2C 2C 97 06", "PC-E Nikkor 24mm f/3.5D ED"}, {"95 4C 37 37 2C 2C 97 02", "PC-E Nikkor 24mm f/3.5D ED"}, {"96 38 1F 37 34 3C 4B 06", "Sigma 12-24mm f/4.5-5.6 II DG HSM"}, @@ -1002,6 +1006,7 @@ const std::map NALensDataInterpreter::lenses = { {"A7 3C 53 80 30 3C C2 0E", "AF-S DX Nikkor 55-200mm f/4-5.6G ED VR II"}, {"A7 49 80 A0 24 24 4B 06", "Sigma APO 200-500mm f/2.8 EX DG"}, {"A7 4B 62 62 2C 2C A9 0E", "AF-S DX Micro Nikkor 85mm f/3.5G ED VR"}, + {"A8 38 18 30 34 3C D3 8E", "AF-P DX Nikkor 10-20mm f/4.5-5.6G VR"}, {"A8 48 80 98 30 30 AA 0E", "AF-S VR Zoom-Nikkor 200-400mm f/4G IF-ED II"}, {"A8 48 8E 8E 30 30 C3 0E", "AF-S Nikkor 300mm f/4E PF ED VR"}, {"A8 48 8E 8E 30 30 C3 4E", "AF-S Nikkor 300mm f/4E PF ED VR"}, @@ -1030,6 +1035,8 @@ const std::map NALensDataInterpreter::lenses = { {"B6 48 37 56 24 24 1C 02", "Sigma 24-60mm f/2.8 EX DG"}, {"B7 44 60 98 34 3C B9 0E", "AF-S Nikkor 80-400mm f/4.5-5.6G ED VR"}, {"B8 40 2D 44 2C 34 BA 06", "AF-S Nikkor 18-35mm f/3.5-4.5G ED"}, + {"BF 4E 26 26 1E 1E 01 04", "Irix 15mm f/2.4 Firefly"}, + {"C3 34 68 98 38 40 4B 4E", "Sigma 100-400mm f/5-6.3 DG OS HSM | C"}, {"CC 4C 50 68 14 14 4B 06", "Sigma 50-100mm f/1.8 DC HSM | A"}, {"CD 3D 2D 70 2E 3C 4B 0E", "Sigma 18-125mm f/3.8-5.6 DC OS HSM"}, {"CE 34 76 A0 38 40 4B 0E", "Sigma 150-500mm f/5-6.3 DG OS APO HSM"}, @@ -1083,7 +1090,7 @@ const std::map NALensDataInterpreter::lenses = { {"FE 53 5C 80 24 24 84 06", "Tamron SP AF 70-200mm f/2.8 Di LD (IF) Macro (A001)"}, {"FE 54 5C 80 24 24 DF 0E", "Tamron SP 70-200mm f/2.8 Di VC USD (A009)"}, {"FE 54 64 64 24 24 DF 0E", "Tamron SP 90mm f/2.8 Di VC USD Macro 1:1 (F004)"}, - {"FF 40 2D 80 2C 40 4B 06", "Sigma 18-200mm f/3.5-6.3 DC"} + {"FF 40 2D 80 2C 40 4B 06", "Sigma 18-200mm f/3.5-6.3 DC"}, }; const TagAttrib nikonISOInfoAttribs[] = { diff --git a/rtexif/pentaxattribs.cc b/rtexif/pentaxattribs.cc index 2c52a0c88..7444e7212 100644 --- a/rtexif/pentaxattribs.cc +++ b/rtexif/pentaxattribs.cc @@ -928,6 +928,7 @@ public: choices.insert (p_t (256 * 8 + 30, "Sigma 17-70mm f/2.8-4 DC Macro HSM | C")); choices.insert (p_t (256 * 8 + 31, "Sigma 18-35mm f/1.8 DC HSM")); choices.insert (p_t (256 * 8 + 32, "Sigma 30mm f/1.4 DC HSM | A")); + choices.insert (p_t (256 * 8 + 33, "Sigma 18-200mm f/3.5-6.3 DC MACRO HSM")); choices.insert (p_t (256 * 8 + 34, "Sigma 18-300mm f/3.5-6.3 DC Macro HSM")); choices.insert (p_t (256 * 8 + 59, "HD PENTAX-D FA 150-450mm f/4.5-5.6 ED DC AW")); choices.insert (p_t (256 * 8 + 60, "HD PENTAX-D FA* 70-200mm f/2.8 ED DC AW")); @@ -977,6 +978,7 @@ public: choices.insert (p_t (256 * 13 + 19, "smc PENTAX-D FA 645 25mm f/4 AL [IF] SDM AW")); choices.insert (p_t (256 * 13 + 20, "HD PENTAX-D FA 645 90mm f/2.8 ED AW SR")); choices.insert (p_t (256 * 13 + 253, "HD PENTAX-DA 645 28-45mm f/4.5 ED AW SR")); + choices.insert (p_t (256 * 13 + 254, "smc PENTAX-DA 645 25mm f/4 AL [IF] SDM AW")); choices.insert (p_t (256 * 21 + 0, "Pentax Q Manual Lens")); choices.insert (p_t (256 * 21 + 1, "01 Standard Prime 8.5mm f/1.9")); choices.insert (p_t (256 * 21 + 2, "02 Standard Zoom 5-15mm f/2.8-4.5")); @@ -1228,6 +1230,7 @@ public: choices[2] = "HDR 1"; choices[3] = "HDR 2"; choices[4] = "HDR 3"; + choices[5] = "Advanced"; choices1[0] = "Auto-align Off"; choices1[1] = "Auto-align On"; @@ -1334,7 +1337,7 @@ public: sprintf (buffer, "%d", a ); return buffer; } - virtual double toDouble (Tag* t, int ofs) + virtual double toDouble (const Tag* t, int ofs) { int a; @@ -1365,7 +1368,7 @@ public: return "n/a"; } } - virtual double toDouble (Tag* t, int ofs) + virtual double toDouble (const Tag* t, int ofs) { double a = double (t->toInt (0, LONG)); @@ -1395,7 +1398,7 @@ public: return "n/a"; } } - virtual double toDouble (Tag* t, int ofs) + virtual double toDouble (const Tag* t, int ofs) { int a = t->toInt (ofs, BYTE); float b = float (10 * int (a >> 2)) * pow (4.f, float (int (a & 0x03) - 2)); @@ -1421,7 +1424,7 @@ public: sprintf (buffer, "%.1f", v ); return buffer; } - virtual double toDouble (Tag* t, int ofs) + virtual double toDouble (const Tag* t, int ofs) { int a = t->toInt (0, BYTE); return 100.*exp (double (a - 32) * log (2.) / 8.); @@ -1452,7 +1455,7 @@ public: return "n/a"; } } - virtual double toDouble (Tag* t, int ofs) + virtual double toDouble (const Tag* t, int ofs) { int a = t->toInt (0, BYTE); a &= 0x7F; @@ -1478,7 +1481,7 @@ public: sprintf (buffer, "%.1f", v ); return buffer; } - virtual double toDouble (Tag* t, int ofs) + virtual double toDouble (const Tag* t, int ofs) { int a = t->toInt (0, BYTE); return double (a - 64) / 8.; @@ -1498,7 +1501,7 @@ public: sprintf (buffer, "%.1f", v ); return buffer; } - virtual double toDouble (Tag* t, int ofs) + virtual double toDouble (const Tag* t, int ofs) { int a = t->toInt (0, SBYTE); return double (a) / 8.; @@ -1518,7 +1521,7 @@ public: sprintf (buffer, "%.1f", v ); return buffer; } - virtual double toDouble (Tag* t, int ofs) + virtual double toDouble (const Tag* t, int ofs) { int a = t->toInt (0, BYTE); return exp ((double (a) - 68.) * log (2.) / 16.); @@ -1538,7 +1541,7 @@ public: sprintf (buffer, "%.6f", v ); return buffer; } - virtual double toDouble (Tag* t, int ofs) + virtual double toDouble (const Tag* t, int ofs) { int a = t->toInt (0, BYTE); return 24.*exp (- (double (a) - 32.) * log (2.) / 8.); @@ -1558,7 +1561,7 @@ public: sprintf (buffer, "%.1f", double (int (pow (2.0, double (mina + 10) / 4.0) + 0.2))); return buffer; } - virtual double toDouble (Tag* t, int ofs) + virtual double toDouble (const Tag* t, int ofs) { int a = t->toInt (0, BYTE) & 0x0F; return double (int (pow (2.0, double (a + 10) / 4.0) + 0.2)); @@ -1578,7 +1581,7 @@ public: sprintf (buffer, "%.1f", double (int (pow (2.0, double (maxa) / 4.0) + 0.2)) ); return buffer; } - virtual double toDouble (Tag* t, int ofs) + virtual double toDouble (const Tag* t, int ofs) { int a = ( t->toInt (0, BYTE) & 0xF0) >> 4; return double (int (pow (2.0, double (a) / 4.0) + 0.2)); diff --git a/rtexif/rtexif.cc b/rtexif/rtexif.cc index c12f5f782..bc0e2002f 100644 --- a/rtexif/rtexif.cc +++ b/rtexif/rtexif.cc @@ -19,13 +19,16 @@ * along with RawTherapee. If not, see . */ #include +#include #include #include #include #include #include +#include #include +#include #include "rtexif.h" @@ -33,6 +36,9 @@ #include "../rtgui/version.h" #include "../rtgui/ppversion.h" +// see end of ExifManager::parse(bool, bool) +#define PRINT_METADATA_TREE 0 + using namespace std; namespace rtexif @@ -44,8 +50,6 @@ Interpreter stdInterpreter; // this class is a collection (an array) of tags //----------------------------------------------------------------------------- -#define TAG_SUBFILETYPE 0x00fe - TagDirectory::TagDirectory () : attribs (ifdAttribs), order (HOSTORDER), parent (nullptr) {} @@ -78,7 +82,7 @@ TagDirectory::TagDirectory (TagDirectory* p, FILE* f, int base, const TagAttrib* int id = newTag->getID(); // detect and possibly ignore tags of directories belonging to the embedded thumbnail image - if (attribs == ifdAttribs && id == TAG_SUBFILETYPE && newTag->toInt() != 0) { + if (attribs == ifdAttribs && id == TIFFTAG_SUBFILETYPE && newTag->toInt() != 0) { thumbdescr = true; } @@ -207,11 +211,14 @@ void TagDirectory::printAll (unsigned int level) const for (size_t i = 0; i < tags.size(); i++) { std::string name = tags[i]->nameToString (); + TagDirectory* currTagDir; if (tags[i]->isDirectory()) { - for (int j = 0; tags[i]->getDirectory (j); j++) { + for (int j = 0; (currTagDir = tags[i]->getDirectory (j)) != nullptr; j++) { printf ("%s+-- DIRECTORY %s[%d]:\n", prefixStr, name.c_str(), j); - tags[i]->getDirectory (j)->printAll (level + 1); + currTagDir->printAll (level + 1); } + } else { + printf ("%s- %s\n", prefixStr, name.c_str()); } } } @@ -285,6 +292,10 @@ bool TagDirectory::CPBDump (const Glib::ustring &commFName, const Glib::ustring kf->set_string ("RT General", "DefaultProcParams", defaultPParams); kf->set_boolean ("RT General", "FlaggingMode", flagMode); + kf->set_integer ("Common Data", "FrameCount", cfs->frameCount); + kf->set_integer ("Common Data", "SampleFormat", cfs->sampleFormat); + kf->set_boolean ("Common Data", "IsHDR", cfs->isHDR); + kf->set_boolean ("Common Data", "IsPixelShift", cfs->isPixelShift); kf->set_double ("Common Data", "FNumber", cfs->fnumber); kf->set_double ("Common Data", "Shutter", cfs->shutter); kf->set_double ("Common Data", "FocalLength", cfs->focalLen); @@ -445,34 +456,126 @@ Tag* TagDirectory::getTagP (const char* name) const return nullptr; } -Tag* TagDirectory::findTag (const char* name) const +Tag* TagDirectory::findTag (const char* name, bool lookUpward) const { - if (attribs) { - for (int i = 0; attribs[i].ignore != -1; i++) - if (!strcmp (attribs[i].name, name)) { - Tag* t = getTag (attribs[i].ID); + Tag* t = getTag(name); + if (t) { + return t; + } + + for (auto tag : tags) { + if (tag->isDirectory()) { + TagDirectory *dir; + int i = 0; + while ((dir = tag->getDirectory(i)) != nullptr) { + TagDirectory *dir = tag->getDirectory(); + Tag* t = dir->findTag (name); if (t) { return t; - } else { - break; } - } - } - - for (size_t i = 0; i < tags.size(); i++) - if (tags[i]->isDirectory()) { - TagDirectory *dir = tags[i]->getDirectory(); - Tag* t = dir->findTag (name); - - if (t) { - return t; + ++i; } } + } + + if (lookUpward && parent) { + Tag* t = parent->findTagUpward(name); + + if (t) { + return t; + } + } return nullptr; } +std::vector TagDirectory::findTags (int ID) +{ + + std::vector tagList; + + //assuming that an entry can only exist once + Tag* t = getTag(ID); + if (t) { + tagList.push_back(t); + } + + for (auto tag : tags) { + if (tag->isDirectory()) { + TagDirectory *dir; + int i = 0; + while ((dir = tag->getDirectory(i)) != nullptr) { + std::vector subTagList = dir->findTags (ID); + + if (!subTagList.empty()) { + // concatenating the 2 vectors + // not really optimal in a memory efficiency pov + for (auto tag2 : subTagList) { + tagList.push_back(tag2); + } + } + ++i; + } + } + } + + return tagList; +} + +std::vector TagDirectory::findTags (const char* name) +{ + + std::vector tagList; + + //assuming that an entry can only exist once + Tag* t = getTag(name); + if (t) { + tagList.push_back(t); + } + + for (auto tag : tags) { + if (tag->isDirectory()) { + TagDirectory *dir; + int i = 0; + while ((dir = tag->getDirectory(i)) != nullptr) { + std::vector subTagList = dir->findTags (name); + + if (!subTagList.empty()) { + // concatenating the 2 vectors + // not really optimal in a memory efficiency pov, but adding 10 items should be a maximum + for (auto tag2 : subTagList) { + tagList.push_back(tag2); + } + } + ++i; + } + } + } + + return tagList; +} + + +Tag* TagDirectory::findTagUpward (const char* name) const +{ + Tag* t = findTag(name); + if (t) { + return t; + } + + if (parent) { + Tag* t = parent->findTagUpward(name); + + if (t) { + return t; + } + } + + return nullptr; +} + + // Searches a simple value, as either attribute or element // only for simple values, not for entries with special chars or free text bool TagDirectory::getXMPTagValue (const char* name, char* value) const @@ -605,7 +708,7 @@ int TagDirectory::write (int start, unsigned char* buffer) return maxPos; } -void TagDirectory::applyChange (std::string name, std::string value) +void TagDirectory::applyChange (std::string name, Glib::ustring value) { std::string::size_type dp = name.find_first_of ('.'); @@ -627,7 +730,12 @@ void TagDirectory::applyChange (std::string name, std::string value) } else if (value == "#delete" && t) { t->setKeep (false); } else if (t && !t->isDirectory()) { - t->valueFromString (value); + if (name == "UserComment") { + // UserComment can be Unicode + t->userCommentFromString (value); + } else { + t->valueFromString (value); + } } else { const TagAttrib* attrib = nullptr; @@ -639,7 +747,12 @@ void TagDirectory::applyChange (std::string name, std::string value) if (attrib) { Tag* nt = new Tag (this, attrib); - nt->initString (value.c_str()); + if (name == "UserComment") { + // UserComment can be Unicode + nt->initUserComment (value); + } else { + nt->initString (value.c_str()); + } addTag (nt); } } @@ -849,9 +962,11 @@ Tag::Tag (TagDirectory* p, FILE* f, int base) } if (tag == 0x002e) { // location of the embedded preview image in raw files of Panasonic cameras - TagDirectory* previewdir = ExifManager::parseJPEG (f, ftell (f)); // try to parse the exif data from the preview image + ExifManager eManager(f, nullptr, true); + eManager.parseJPEG(ftell(f)); // try to parse the exif data from the preview image - if (previewdir) { + if (eManager.roots.size()) { + const TagDirectory* const previewdir = eManager.roots.at(0); if (previewdir->getTag ("Exif")) { if (previewdir->getTag ("Make")) { if (previewdir->getTag ("Make")->valueToString() == "Panasonic") { // "make" is not yet available here, so get it from the preview tags to assure we're doing the right thing @@ -1351,7 +1466,7 @@ void Tag::fromString (const char* v, int size) } } -int Tag::toInt (int ofs, TagType astype) +int Tag::toInt (int ofs, TagType astype) const { if (attrib) { return attrib->interpreter->toInt (this, ofs, astype); @@ -1402,7 +1517,7 @@ int Tag::toInt (int ofs, TagType astype) return 0; } -double Tag::toDouble (int ofs) +double Tag::toDouble (int ofs) const { if (attrib) { return attrib->interpreter->toDouble (this, ofs); @@ -1642,6 +1757,19 @@ void Tag::valueFromString (const std::string& value) } } +void Tag::userCommentFromString (const Glib::ustring& text) +{ + + if (!allocOwnMemory) { + return; + } + if (value) { + delete [] value; + value = nullptr; + } + initUserComment(text); +} + int Tag::calculateSize () { int size = 0; @@ -1803,6 +1931,28 @@ void Tag::initInt (int data, TagType t, int cnt) setInt (data, 0, t); } +void Tag::initUserComment (const Glib::ustring &text) +{ + type = UNDEFINED; + if (text.is_ascii()) { + count = 8 + strlen (text.c_str()); + valuesize = count; + value = new unsigned char[valuesize]; + strcpy ((char*)value, "ASCII"); + value[5] = value[6] = value[7] = 0; + strcpy ((char*)value + 8, text.c_str()); + } else { + wchar_t *commentStr = (wchar_t*)g_utf8_to_utf16 (text.c_str(), -1, NULL, NULL, NULL); + count = 8 + wcslen(commentStr)*2; + valuesize = count; + value = (unsigned char*)new char[valuesize]; + strcpy ((char*)value, "UNICODE"); + value[7] = 0; + wcscpy(((wchar_t*)value) + 4, commentStr); + g_free(commentStr); + } +} + void Tag::initString (const char* text) { @@ -1893,8 +2043,12 @@ const TagAttrib* lookupAttrib (const TagAttrib* dir, const char* field) return nullptr; } +void ExifManager::setIFDOffset(unsigned int offset) +{ + IFDOffset = offset; +} -TagDirectory* ExifManager::parseCIFF (FILE* f, int base, int length) +void ExifManager::parseCIFF () { TagDirectory* root = new TagDirectory (nullptr, ifdAttribs, INTEL); @@ -1904,12 +2058,11 @@ TagDirectory* ExifManager::parseCIFF (FILE* f, int base, int length) mn->initMakerNote (IFD, canonAttribs); root->addTag (exif); exif->getDirectory()->addTag (mn); - parseCIFF (f, base, length, root); + parseCIFF (rml->ciffLength, root); root->sort (); - return root; } -Tag* ExifManager::saveCIFFMNTag (FILE* f, TagDirectory* root, int len, const char* name) +Tag* ExifManager::saveCIFFMNTag (TagDirectory* root, int len, const char* name) { int s = ftell (f); if(s >= 0) { @@ -1927,15 +2080,22 @@ Tag* ExifManager::saveCIFFMNTag (FILE* f, TagDirectory* root, int len, const cha } } -void ExifManager::parseCIFF (FILE* f, int base, int length, TagDirectory* root) +void ExifManager::parseCIFF (int length, TagDirectory* root) { + if (!f) { + #ifndef NDEBUG + std::cerr << "ERROR : no file opened !" << std::endl; + #endif + return; + } + char buffer[1024]; Tag* t; - fseek (f, base + length - 4, SEEK_SET); + fseek (f, rml->ciffBase + length - 4, SEEK_SET); - int dirStart = get4 (f, INTEL) + base; + int dirStart = get4 (f, INTEL) + rml->ciffBase; fseek (f, dirStart, SEEK_SET); int numOfTags = get2 (f, INTEL); @@ -1960,10 +2120,19 @@ void ExifManager::parseCIFF (FILE* f, int base, int length, TagDirectory* root) int nextPos = ftell (f) + 4; // seek to the location of the value - fseek (f, base + get4 (f, INTEL), SEEK_SET); + fseek (f, rml->ciffBase + get4 (f, INTEL), SEEK_SET); if ((((type >> 8) + 8) | 8) == 0x38) { - parseCIFF (f, ftell (f), len, root); // Parse a sub-table + ExifManager( + f, + std::unique_ptr( + new rtengine::RawMetaDataLocation( + ftell(f), + len + ) + ), + true + ).parseCIFF(len, root); // Parse a sub-table } if (type == 0x0810) { @@ -1994,8 +2163,9 @@ void ExifManager::parseCIFF (FILE* f, int base, int length, TagDirectory* root) } + ExifManager exifManager(f, nullptr, true); if (type == 0x102d) { - Tag* t = saveCIFFMNTag (f, root, len, "CanonCameraSettings"); + Tag* t = exifManager.saveCIFFMNTag (root, len, "CanonCameraSettings"); int mm = t->toInt (34, SHORT); Tag* nt = new Tag (exif, lookupAttrib (exifAttribs, "MeteringMode")); @@ -2074,31 +2244,31 @@ void ExifManager::parseCIFF (FILE* f, int base, int length, TagDirectory* root) } if (type == 0x1029) { - saveCIFFMNTag (f, root, len, "CanonFocalLength"); + exifManager.saveCIFFMNTag (root, len, "CanonFocalLength"); } if (type == 0x1031) { - saveCIFFMNTag (f, root, len, "SensorInfo"); + exifManager.saveCIFFMNTag (root, len, "SensorInfo"); } if (type == 0x1033) { - saveCIFFMNTag (f, root, len, "CustomFunctions"); + exifManager.saveCIFFMNTag (root, len, "CustomFunctions"); } if (type == 0x1038) { - saveCIFFMNTag (f, root, len, "CanonAFInfo"); + exifManager.saveCIFFMNTag (root, len, "CanonAFInfo"); } if (type == 0x1093) { - saveCIFFMNTag (f, root, len, "CanonFileInfo"); + exifManager.saveCIFFMNTag (root, len, "CanonFileInfo"); } if (type == 0x10a9) { - saveCIFFMNTag (f, root, len, "ColorBalance"); + exifManager.saveCIFFMNTag (root, len, "ColorBalance"); } if (type == 0x102a) { - saveCIFFMNTag (f, root, len, "CanonShotInfo"); + exifManager.saveCIFFMNTag (root, len, "CanonShotInfo"); iso = pow (2, (get4 (f, INTEL), get2 (f, INTEL)) / 32.0 - 4) * 50; aperture = (get2 (f, INTEL), (short)get2 (f, INTEL)) / 32.0f; @@ -2193,6 +2363,9 @@ void ExifManager::parseCIFF (FILE* f, int base, int length, TagDirectory* root) t->initString (buffer); root->addTag (t); } + + roots.push_back(root); + } static void @@ -2530,33 +2703,65 @@ parse_leafdata (TagDirectory* root, ByteOrder order) } } -TagDirectory* ExifManager::parse (FILE* f, int base, bool skipIgnored) +void ExifManager::parseRaw (bool skipIgnored) { + parse(true, skipIgnored); +} + +void ExifManager::parseStd (bool skipIgnored) { + parse(false, skipIgnored); +} + +void ExifManager::parse (bool isRaw, bool skipIgnored) { + int ifdOffset = IFDOffset; + + if (!f) { + #ifndef NDEBUG + std::cerr << "ERROR : no file opened !" << std::endl; + #endif + return; + } setlocale (LC_NUMERIC, "C"); // to set decimal point in sscanf - // read tiff header - fseek (f, base, SEEK_SET); - unsigned short bo; - fread (&bo, 1, 2, f); - ByteOrder order = (ByteOrder) ((int)bo); - get2 (f, order); - int firstifd = get4 (f, order); - // seek to IFD0 - fseek (f, base + firstifd, SEEK_SET); + if (order == ByteOrder::UNKNOWN) { + // read tiff header + fseek (f, rml->exifBase, SEEK_SET); + unsigned short bo; + fread (&bo, 1, 2, f); + order = (ByteOrder) ((int)bo); + get2 (f, order); + if (!ifdOffset) { + ifdOffset = get4 (f, order); + } + } - // first read the IFD directory - TagDirectory* root = new TagDirectory (nullptr, f, base, ifdAttribs, order, skipIgnored); + do { + // seek to IFD + fseek (f, rml->exifBase + ifdOffset, SEEK_SET); - // fix ISO issue with nikon and panasonic cameras - Tag* make = root->getTag ("Make"); - Tag* exif = root->getTag ("Exif"); + // first read the IFD directory + TagDirectory* root = new TagDirectory (nullptr, f, rml->exifBase, ifdAttribs, order, skipIgnored); - if (exif && !exif->getDirectory()->getTag ("ISOSpeedRatings")) { - if (make && !strncmp ((char*)make->getValue(), "NIKON", 5)) { - Tag* mn = exif->getDirectory()->getTag ("MakerNote"); + // fix ISO issue with nikon and panasonic cameras + Tag* make = root->getTag ("Make"); + Tag* exif = root->getTag ("Exif"); - if (mn) { - Tag* iso = mn->getDirectory()->getTag ("ISOSpeed"); + if (exif && !exif->getDirectory()->getTag ("ISOSpeedRatings")) { + if (make && !strncmp ((char*)make->getValue(), "NIKON", 5)) { + Tag* mn = exif->getDirectory()->getTag ("MakerNote"); + + if (mn) { + Tag* iso = mn->getDirectory()->getTag ("ISOSpeed"); + + if (iso) { + std::string isov = iso->valueToString (); + Tag* niso = new Tag (exif->getDirectory(), exif->getDirectory()->getAttrib ("ISOSpeedRatings")); + niso->initInt (atoi (isov.c_str()), SHORT); + exif->getDirectory()->addTagFront (niso); + } + } + } else if (make && (!strncmp ((char*)make->getValue(), "Panasonic", 9) || !strncmp ((char*)make->getValue(), "LEICA", 5))) { + Tag* iso = root->getTag ("PanaISO"); if (iso) { std::string isov = iso->valueToString (); @@ -2565,225 +2770,310 @@ TagDirectory* ExifManager::parse (FILE* f, int base, bool skipIgnored) exif->getDirectory()->addTagFront (niso); } } - } else if (make && (!strncmp ((char*)make->getValue(), "Panasonic", 9) || !strncmp ((char*)make->getValue(), "LEICA", 5))) { - Tag* iso = root->getTag ("PanaISO"); - - if (iso) { - std::string isov = iso->valueToString (); - Tag* niso = new Tag (exif->getDirectory(), exif->getDirectory()->getAttrib ("ISOSpeedRatings")); - niso->initInt (atoi (isov.c_str()), SHORT); - exif->getDirectory()->addTagFront (niso); - } } - } - if (make && !strncmp ((char*)make->getValue(), "Kodak", 5)) { - if (!exif) { - // old Kodak cameras may have exif tags in IFD0, reparse and create an exif subdir - fseek (f, base + firstifd, SEEK_SET); - TagDirectory* exifdir = new TagDirectory (nullptr, f, base, exifAttribs, order, true); + if (make && !strncmp ((char*)make->getValue(), "Kodak", 5)) { + if (!exif) { + // old Kodak cameras may have exif tags in IFD0, reparse and create an exif subdir + fseek (f, rml->exifBase + ifdOffset, SEEK_SET); + TagDirectory* exifdir = new TagDirectory (nullptr, f, rml->exifBase, exifAttribs, order, true); - exif = new Tag (root, root->getAttrib ("Exif")); - exif->initSubDir (exifdir); - root->addTagFront (exif); + exif = new Tag (root, root->getAttrib ("Exif")); + exif->initSubDir (exifdir); + root->addTagFront (exif); - if (!exif->getDirectory()->getTag ("ISOSpeedRatings") && exif->getDirectory()->getTag ("ExposureIndex")) { - Tag* niso = new Tag (exif->getDirectory(), exif->getDirectory()->getAttrib ("ISOSpeedRatings")); - niso->initInt (exif->getDirectory()->getTag ("ExposureIndex")->toInt(), SHORT); - exif->getDirectory()->addTagFront (niso); + if (!exif->getDirectory()->getTag ("ISOSpeedRatings") && exif->getDirectory()->getTag ("ExposureIndex")) { + Tag* niso = new Tag (exif->getDirectory(), exif->getDirectory()->getAttrib ("ISOSpeedRatings")); + niso->initInt (exif->getDirectory()->getTag ("ExposureIndex")->toInt(), SHORT); + exif->getDirectory()->addTagFront (niso); + } + } + + Tag *kodakIFD = root->getTag ("KodakIFD"); + + if (kodakIFD && kodakIFD->getDirectory()->getTag ("TextualInfo")) { + parseKodakIfdTextualInfo (kodakIFD->getDirectory()->getTag ("TextualInfo"), exif); } } - Tag *kodakIFD = root->getTag ("KodakIFD"); + parse_leafdata (root, order); - if (kodakIFD && kodakIFD->getDirectory()->getTag ("TextualInfo")) { - parseKodakIfdTextualInfo (kodakIFD->getDirectory()->getTag ("TextualInfo"), exif); - } - } + if (make && !strncmp ((char*)make->getValue(), "Hasselblad", 10)) { + /* + Figuring out the Hasselblad model is a mess. Hasselblad raw data comes in four slightly + different containers, 3FR (directly from CF card), FFF (same as 3FR but filtered through + Phocus, calibration data applied and a bit different tags), Adobe-generated DNGs and + Phocus-generated DNGs. - parse_leafdata (root, order); + FFF usually has a sane model name in Model (and is used as reference for what we shall + call the different Hasselblad models), but 3FR only says like "Hasselblad H3D" for + all H3D models, or "Flash Sync" if the back has been used on a mechanical camera body. + V-mount backs may have the model name of the V body instead of the back model. Etc... + as said it's a mess. - if (make && !strncmp ((char*)make->getValue(), "Hasselblad", 10)) { - /* - Figuring out the Hasselblad model is a mess. Hasselblad raw data comes in four slightly - different containers, 3FR (directly from CF card), FFF (same as 3FR but filtered through - Phocus, calibration data applied and a bit different tags), Adobe-generated DNGs and - Phocus-generated DNGs. + This code is supposed to handle all raw containers and end up with the same model + regardless of container. - FFF usually has a sane model name in Model (and is used as reference for what we shall - call the different Hasselblad models), but 3FR only says like "Hasselblad H3D" for - all H3D models, or "Flash Sync" if the back has been used on a mechanical camera body. - V-mount backs may have the model name of the V body instead of the back model. Etc... - as said it's a mess. + We don't differ between single shot and multi-shot models, and probably there's no use + of doing so. You need Hasselblad's own software to shoot multi-shot and can only do that + tethered. In single-shot mode they should be exactly the same as the single-shot models. + */ + Tag *subd = root->getTag (0x14a); + Tag *iw = (subd) ? subd->getDirectory()->getTag ("ImageWidth") : nullptr; + int sensorWidth = (iw) ? iw->toInt() : 0; + Tag* tmodel = root->getTag ("Model"); + const char *model = (tmodel) ? (const char *)tmodel->getValue() : ""; - This code is supposed to handle all raw containers and end up with the same model - regardless of container. + if (strstr (model, "Hasselblad ") == model) { + model += 11; + } else { + // if HxD is used in flash sync mode for example, we need to fetch model from this tag + Tag* tmodel3 = root->getTag ("UniqueCameraModel"); + const char *model3 = (tmodel3) ? (const char *)tmodel3->getValue() : ""; - We don't differ between single shot and multi-shot models, and probably there's no use - of doing so. You need Hasselblad's own software to shoot multi-shot and can only do that - tethered. In single-shot mode they should be exactly the same as the single-shot models. - */ - Tag *subd = root->getTag (0x14a); - Tag *iw = (subd) ? subd->getDirectory()->getTag ("ImageWidth") : nullptr; - int sensorWidth = (iw) ? iw->toInt() : 0; - Tag* tmodel = root->getTag ("Model"); - const char *model = (tmodel) ? (const char *)tmodel->getValue() : ""; + if (strstr (model3, "Hasselblad ") == model3) { + model = model3 + 11; + } + } - if (strstr (model, "Hasselblad ") == model) { - model += 11; - } else { - // if HxD is used in flash sync mode for example, we need to fetch model from this tag + // FIXME: due to lack of test files this Hasselblad model identification is not 100% complete + // This needs checking out: CFV-39/CFV-50 3FR, H3DII vs H3D, old CF/CFH models + + if (!strcmp (model, "H3D")) { + // We can't differ between H3D and H3DII for the 22, 31 and 39 models. There's was no H3D-50 so we know that is a + // H3DII-50. At the time of writing I have no test files for the H3D vs H3DII models, so there still may be a chance + // to differ between them. AFAIK Adobe's DNG converter don't differ between them, and actually call the H3DII-50 + // H3D-50 although Hasselblad never released such a model. + switch (sensorWidth) { + case 4096: + tmodel->initString ("H3D-22"); + break; + + case 6542: + tmodel->initString ("H3D-31"); + break; + + case 7262: + tmodel->initString ("H3D-39"); + break; + + case 8282: + tmodel->initString ("H3DII-50"); + break; + } + } else if (!strcmp (model, "H4D")) { + switch (sensorWidth) { + case 6542: + tmodel->initString ("H4D-31"); + break; + + case 7410: + tmodel->initString ("H4D-40"); + break; + + case 8282: + tmodel->initString ("H4D-50"); + break; + + case 9044: + tmodel->initString ("H4D-60"); + break; + } + } else if (!strcmp (model, "H5D")) { + switch (sensorWidth) { + case 7410: + tmodel->initString ("H5D-40"); + break; + + case 8282: + tmodel->initString ("H5D-50"); + break; + + case 8374: + tmodel->initString ("H5D-50c"); + break; + + case 9044: + tmodel->initString ("H5D-60"); + break; + } + } else if (!strcmp (model, "CFV")) { + switch (sensorWidth) { + case 7262: + tmodel->initString ("CFV-39"); + break; + + case 8282: + tmodel->initString ("CFV-50"); + break; + + case 8374: + tmodel->initString ("CFV-50c"); + break; + } + } + + // and a few special cases Tag* tmodel3 = root->getTag ("UniqueCameraModel"); const char *model3 = (tmodel3) ? (const char *)tmodel3->getValue() : ""; if (strstr (model3, "Hasselblad ") == model3) { - model = model3 + 11; - } - } - - // FIXME: due to lack of test files this Hasselblad model identification is not 100% complete - // This needs checking out: CFV-39/CFV-50 3FR, H3DII vs H3D, old CF/CFH models - - if (!strcmp (model, "H3D")) { - // We can't differ between H3D and H3DII for the 22, 31 and 39 models. There's was no H3D-50 so we know that is a - // H3DII-50. At the time of writing I have no test files for the H3D vs H3DII models, so there still may be a chance - // to differ between them. AFAIK Adobe's DNG converter don't differ between them, and actually call the H3DII-50 - // H3D-50 although Hasselblad never released such a model. - switch (sensorWidth) { - case 4096: - tmodel->initString ("H3D-22"); - break; - - case 6542: - tmodel->initString ("H3D-31"); - break; - - case 7262: - tmodel->initString ("H3D-39"); - break; - - case 8282: - tmodel->initString ("H3DII-50"); - break; - } - } else if (!strcmp (model, "H4D")) { - switch (sensorWidth) { - case 6542: - tmodel->initString ("H4D-31"); - break; - - case 7410: - tmodel->initString ("H4D-40"); - break; - - case 8282: - tmodel->initString ("H4D-50"); - break; - - case 9044: - tmodel->initString ("H4D-60"); - break; - } - } else if (!strcmp (model, "H5D")) { - switch (sensorWidth) { - case 7410: - tmodel->initString ("H5D-40"); - break; - - case 8282: - tmodel->initString ("H5D-50"); - break; - - case 8374: - tmodel->initString ("H5D-50c"); - break; - - case 9044: - tmodel->initString ("H5D-60"); - break; - } - } else if (!strcmp (model, "CFV")) { - switch (sensorWidth) { - case 7262: - tmodel->initString ("CFV-39"); - break; - - case 8282: - tmodel->initString ("CFV-50"); - break; - - case 8374: - tmodel->initString ("CFV-50c"); - break; - } - } - - // and a few special cases - Tag* tmodel3 = root->getTag ("UniqueCameraModel"); - const char *model3 = (tmodel3) ? (const char *)tmodel3->getValue() : ""; - - if (strstr (model3, "Hasselblad ") == model3) { - model3 = model3 + 11; - } - - if (!strcmp (model3, "ixpressCF132")) { - tmodel->initString ("CF-22"); - } else if (!strcmp (model3, "Hasselblad96")) { - tmodel->initString ("CFV"); // popularly called CFV-16, but the official name is CFV - } else if (!strcmp (model3, "Hasselblad234")) { - tmodel->initString ("CFV-39"); - } else if (sensorWidth == 4090) { - tmodel->initString ("V96C"); - } - - // and yet some, this is for Adobe-generated DNG files - Tag* tmodel4 = root->getTag ("LocalizedCameraModel"); - - if (tmodel4) { - const char *model4 = (const char *)tmodel4->getValue(); - - if (strstr (model4, "Hasselblad ") == model4) { - model4 = model4 + 11; + model3 = model3 + 11; } - if (!strcmp (model4, "ixpressCF132-22")) { + if (!strcmp (model3, "ixpressCF132")) { tmodel->initString ("CF-22"); - } else if (!strcmp (model4, "Hasselblad96-16")) { - tmodel->initString ("CFV"); - } else if (!strcmp (model4, "Hasselblad234-39")) { + } else if (!strcmp (model3, "Hasselblad96")) { + tmodel->initString ("CFV"); // popularly called CFV-16, but the official name is CFV + } else if (!strcmp (model3, "Hasselblad234")) { tmodel->initString ("CFV-39"); - } else if (!strcmp (model4, "H3D-50")) { - // Adobe names H3DII-50 incorrectly as H3D-50 - tmodel->initString ("H3DII-50"); - } else if (strstr (model4, "H3D-") == model4 || strstr (model4, "H4D-") == model4 || strstr (model4, "H5D-") == model4) { - tmodel->initString (model4); - } - } - } - - if (!root->getTag ("Orientation")) { - if (make && !strncmp ((char*)make->getValue(), "Phase One", 9)) { - int orientation = 0; - Tag *iw = root->getTag ("ImageWidth"); - - if (iw) { - // from dcraw, derive orientation from image width - orientation = "0653"[iw->toInt() & 3] - '0'; + } else if (sensorWidth == 4090) { + tmodel->initString ("V96C"); } - Tag *t = new Tag (root, root->getAttrib ("Orientation")); - t->initInt (orientation, SHORT); - root->addTagFront (t); + // and yet some, this is for Adobe-generated DNG files + Tag* tmodel4 = root->getTag ("LocalizedCameraModel"); + + if (tmodel4) { + const char *model4 = (const char *)tmodel4->getValue(); + + if (strstr (model4, "Hasselblad ") == model4) { + model4 = model4 + 11; + } + + if (!strcmp (model4, "ixpressCF132-22")) { + tmodel->initString ("CF-22"); + } else if (!strcmp (model4, "Hasselblad96-16")) { + tmodel->initString ("CFV"); + } else if (!strcmp (model4, "Hasselblad234-39")) { + tmodel->initString ("CFV-39"); + } else if (!strcmp (model4, "H3D-50")) { + // Adobe names H3DII-50 incorrectly as H3D-50 + tmodel->initString ("H3DII-50"); + } else if (strstr (model4, "H3D-") == model4 || strstr (model4, "H4D-") == model4 || strstr (model4, "H5D-") == model4) { + tmodel->initString (model4); + } + } } + + if (!root->getTag ("Orientation")) { + if (make && !strncmp ((char*)make->getValue(), "Phase One", 9)) { + int orientation = 0; + Tag *iw = root->getTag ("ImageWidth"); + + if (iw) { + // from dcraw, derive orientation from image width + orientation = "0653"[iw->toInt() & 3] - '0'; + } + + Tag *t = new Tag (root, root->getAttrib ("Orientation")); + t->initInt (orientation, SHORT); + root->addTagFront (t); + } + } + + // --- detecting image root IFD based on SubFileType, or if not provided, on PhotometricInterpretation + + bool frameRootDetected = false; + + if(!frameRootDetected) { + std::vector risTagList = root->findTags("RawImageSegmentation"); + if (!risTagList.empty()) { + for (auto ris : risTagList) { + frames.push_back(ris->getParent()); + frameRootDetected = true; + + #if PRINT_METADATA_TREE + printf("\n--------------- FRAME (RAWIMAGESEGMENTATION) ---------------\n\n"); + ris->getParent()->printAll (); + #endif + } + } + } + + if(!frameRootDetected) { + std::vector sftTagList = root->findTags(TIFFTAG_SUBFILETYPE); + if (!sftTagList.empty()) { + for (auto sft : sftTagList) { + int sftVal = sft->toInt(); + if (sftVal == (isRaw ? 0 : 2)) { + frames.push_back(sft->getParent()); + frameRootDetected = true; + +#if PRINT_METADATA_TREE + printf("\n--------------- FRAME (SUBFILETYPE) ---------------\n\n"); + sft->getParent()->printAll (); +#endif + } + } + } + } + + if(!frameRootDetected) { + std::vector sftTagList = root->findTags(TIFFTAG_OSUBFILETYPE); + if (!sftTagList.empty()) { + for (auto sft : sftTagList) { + int sftVal = sft->toInt(); + if (sftVal == OFILETYPE_IMAGE) { + frames.push_back(sft->getParent()); + frameRootDetected = true; + +#if PRINT_METADATA_TREE + printf("\n--------------- FRAME (OSUBFILETYPE) ---------------\n\n"); + sft->getParent()->printAll (); +#endif + } + } + } + } + + if(!frameRootDetected) { + std::vector piTagList = root->findTags("PhotometricInterpretation"); + if (!piTagList.empty()) { + for (auto pi : piTagList) { + int piVal = pi->toInt(); + if (piVal == (isRaw ? 32803 : 2)) { + frames.push_back(pi->getParent()); + //frameRootDetected = true; not used afterward + +#if PRINT_METADATA_TREE + printf("\n--------------- FRAME (PHOTOMETRIC) ---------------\n\n"); + pi->getParent()->printAll (); +#endif + } + } + } + } + + // --- getting next sibling root + + ifdOffset = get4 (f, order); + + roots.push_back(root); + +#if PRINT_METADATA_TREE + printf("\n~~~~~~~~~ ROOT ~~~~~~~~~~~~~~~~~~~~~~~~\n\n"); + root->printAll (); +#endif + + } while (ifdOffset && !onlyFirst); + + // Security check : if there's at least one root, there must be at least one image. + // If the following occurs, then image detection above has failed or it's an unsupported file type. + // Yet the result of this should be valid. + if (!roots.empty() && frames.empty()) { + frames.push_back(roots.at(0)); } - -// root->printAll (); - - return root; } -TagDirectory* ExifManager::parseJPEG (FILE* f, int offset) +void ExifManager::parseJPEG (int offset) { + if (!f) { + #ifndef NDEBUG + std::cerr << "ERROR : no file opened !" << std::endl; + #endif + return; + } if(!fseek (f, offset, SEEK_SET)) { unsigned char c; @@ -2800,25 +3090,39 @@ TagDirectory* ExifManager::parseJPEG (FILE* f, int offset) if (fread (&c, 1, 1, f) && c == 0xe1) { // APP1 marker found if (fread (idbuff, 1, 8, f) < 8) { - return nullptr; + return; } if (!memcmp (idbuff + 2, exifid, 6)) { // Exif info found tiffbase = ftell (f); - return parse (f, tiffbase); + + // We need a RawMetaDataLocation to put the 'tiffbase' value + const bool rmlCreated = !rml; + if (rmlCreated) { + rml.reset(new rtengine::RawMetaDataLocation(0)); + } + rml->exifBase = tiffbase; + parse (false); + if (rmlCreated) { + rml.reset(); + } + return; } } } } } - - return nullptr; } -TagDirectory* ExifManager::parseTIFF (FILE* f, bool skipIgnored) +void ExifManager::parseTIFF (bool skipIgnored) { - - return parse (f, 0, skipIgnored); + if (!rml) { + rml.reset(new rtengine::RawMetaDataLocation(0)); + parse(false, skipIgnored); + rml.reset(); + } else { + parse (false,skipIgnored); + } } std::vector ExifManager::getDefaultTIFFTags (TagDirectory* forthis) diff --git a/rtexif/rtexif.h b/rtexif/rtexif.h index 0167ef445..125d38c94 100644 --- a/rtexif/rtexif.h +++ b/rtexif/rtexif.h @@ -27,10 +27,13 @@ #include #include #include +#include + #include #include "../rtengine/procparams.h" #include "../rtengine/noncopyable.h" +#include "../rtengine/rawmetadatalocation.h" class CacheImageData; @@ -46,9 +49,9 @@ enum ActionCode { AC_INVALID = 100, // invalid state }; -enum ByteOrder {INTEL = 0x4949, MOTOROLA = 0x4D4D}; +enum ByteOrder {UNKNOWN = 0, INTEL = 0x4949, MOTOROLA = 0x4D4D}; #if __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__ -const enum ByteOrder HOSTORDER = INTEL; +const ByteOrder HOSTORDER = INTEL; #else const enum ByteOrder HOSTORDER = MOTOROLA; #endif @@ -99,10 +102,10 @@ class TagDirectory { protected: - std::vector tags; // tags in the directory - const TagAttrib* attribs; // descriptor table to decode the tags - ByteOrder order; // byte order - TagDirectory* parent; // parent directory (NULL if root) + std::vector tags; // tags in the directory + const TagAttrib* attribs; // descriptor table to decode the tags + ByteOrder order; // byte order + TagDirectory* parent; // parent directory (NULL if root) static Glib::ustring getDumpKey (int tagID, const Glib::ustring &tagName); public: @@ -125,16 +128,31 @@ public: return tags.size (); } const TagAttrib* getAttrib (int id); - const TagAttrib* getAttrib (const char* name); // Find a Tag by scanning the whole tag tree and stopping at the first occurrence - const TagAttrib* getAttribP (const char* name); // Try to get the Tag at a given location. 'name' is a path relative to this directory (e.g. "LensInfo/FocalLength") + // Find a Tag by scanning the whole tag tree and stopping at the first occurrence + const TagAttrib* getAttrib (const char* name); + // Try to get the Tag at a given location. 'name' is a path relative to this directory (e.g. "LensInfo/FocalLength") + const TagAttrib* getAttribP (const char* name); const TagAttrib* getAttribTable() { return attribs; } - Tag* getTag (const char* name) const; // Find a Tag by scanning the whole tag tree and stopping at the first occurrence - Tag* getTagP (const char* name) const; // Try to get the Tag at a given location. 'name' is a path relative to this directory (e.g. "LensInfo/FocalLength") + // Find a Tag by scanning the whole tag tree and stopping at the first occurrence + Tag* getTag (const char* name) const; + // Try to get the Tag at a given location. 'name' is a path relative to this directory (e.g. "LensInfo/FocalLength") + Tag* getTagP (const char* name) const; Tag* getTag (int ID) const; - virtual Tag* findTag (const char* name) const; + + // Try to get the Tag in the current directory and in subdirectories + // if lookUpward = true, it will scan the parents TagDirectory up to the root one, + // but w/o looking into their subdirs + virtual Tag* findTag (const char* name, bool lookUpward = false) const; + // Find a all Tags with the given name by scanning the whole tag tree + std::vector findTags (const char* name); + // Find a all Tags with the given ID by scanning the whole tag tree + std::vector findTags (int ID); + // Try to get the Tag in the current directory and in parent directories + // (won't look into subdirs) + virtual Tag* findTagUpward (const char* name) const; bool getXMPTagValue (const char* name, char* value) const; void keepTag (int ID); @@ -153,7 +171,7 @@ public: virtual int calculateSize (); virtual int write (int start, unsigned char* buffer); virtual TagDirectory* clone (TagDirectory* parent); - virtual void applyChange (std::string field, std::string value); + virtual void applyChange (std::string field, Glib::ustring value); virtual void printAll (unsigned int level = 0) const; // reentrant debug function, keep level=0 on first call ! virtual bool CPBDump (const Glib::ustring &commFName, const Glib::ustring &imageFName, const Glib::ustring &profileFName, const Glib::ustring &defaultPParams, @@ -207,15 +225,16 @@ public: Tag (TagDirectory* parent, const TagAttrib* attr, const char* data); // create a new tag from array (used ~Tag (); - void initType (unsigned char *data, TagType type); - void initInt (int data, TagType t, int count = 1); - void initString (const char* text); - void initSubDir (); - void initSubDir (TagDirectory* dir); - void initMakerNote (MNKind mnk, const TagAttrib* ta); - void initUndefArray (const char* data, int len); - void initLongArray (const char* data, int len); - void initRational (int num, int den); + void initType (unsigned char *data, TagType type); + void initInt (int data, TagType t, int count = 1); + void initUserComment (const Glib::ustring &text); + void initString (const char* text); + void initSubDir (); + void initSubDir (TagDirectory* dir); + void initMakerNote (MNKind mnk, const TagAttrib* ta); + void initUndefArray (const char* data, int len); + void initLongArray (const char* data, int len); + void initRational (int num, int den); // get basic tag properties int getID () const @@ -260,9 +279,9 @@ public: } // read/write value - int toInt (int ofs = 0, TagType astype = INVALID); + int toInt (int ofs = 0, TagType astype = INVALID) const; void fromInt (int v); - double toDouble (int ofs = 0); + double toDouble (int ofs = 0) const; double *toDoubleArray (int ofs = 0); void toRational (int& num, int& denom, int ofs = 0); void toString (char* buffer, int ofs = 0); @@ -271,9 +290,10 @@ public: // additional getter/setter for more comfortable use - std::string valueToString (); - std::string nameToString (int i = 0); - void valueFromString (const std::string& value); + std::string valueToString (); + std::string nameToString (int i = 0); + void valueFromString (const std::string& value); + void userCommentFromString (const Glib::ustring& text); // functions for writing int calculateSize (); @@ -309,13 +329,31 @@ public: class ExifManager { - static Tag* saveCIFFMNTag (FILE* f, TagDirectory* root, int len, const char* name); + Tag* saveCIFFMNTag (TagDirectory* root, int len, const char* name); + void parseCIFF (int length, TagDirectory* root); + void parse (bool isRaw, bool skipIgnored = true); + public: - static TagDirectory* parse (FILE*f, int base, bool skipIgnored = true); - static TagDirectory* parseJPEG (FILE*f, int offset = 0); // offset: to extract exif data from a embedded preview/thumbnail - static TagDirectory* parseTIFF (FILE*f, bool skipIgnored = true); - static TagDirectory* parseCIFF (FILE* f, int base, int length); - static void parseCIFF (FILE* f, int base, int length, TagDirectory* root); + FILE* f; + std::unique_ptr rml; + ByteOrder order; + bool onlyFirst; // Only first IFD + unsigned int IFDOffset; + std::vector roots; + std::vector frames; + + ExifManager (FILE* fHandle, std::unique_ptr _rml, bool onlyFirstIFD) + : f(fHandle), rml(std::move(_rml)), order(UNKNOWN), onlyFirst(onlyFirstIFD), + IFDOffset(0) {} + + void setIFDOffset(unsigned int offset); + + + void parseRaw (bool skipIgnored = true); + void parseStd (bool skipIgnored = true); + void parseJPEG (int offset = 0); // offset: to extract exif data from a embedded preview/thumbnail + void parseTIFF (bool skipIgnored = true); + void parseCIFF (); /// @brief Get default tag for TIFF /// @param forthis The byte order will be taken from the given directory. @@ -352,7 +390,7 @@ public: } } // Get the value as a double - virtual double toDouble (Tag* t, int ofs = 0) + virtual double toDouble (const Tag* t, int ofs = 0) { double ud, dd; @@ -393,7 +431,7 @@ public: } } // Get the value as an int - virtual int toInt (Tag* t, int ofs = 0, TagType astype = INVALID) + virtual int toInt (const Tag* t, int ofs = 0, TagType astype = INVALID) { int a; diff --git a/rtexif/sonyminoltaattribs.cc b/rtexif/sonyminoltaattribs.cc index 7195bf8e5..083affa72 100644 --- a/rtexif/sonyminoltaattribs.cc +++ b/rtexif/sonyminoltaattribs.cc @@ -664,7 +664,13 @@ public: {128, "Sigma 35mm f/1.4 DG HSM"}, {128, "Sigma 18-35mm f/1.8 DC HSM"}, {128, "Sigma 50-500mm f/4.5-6.3 APO DG OS HSM"}, - {128, "Sigma 24-105mm f/4 DG HSM | Art 013"}, + {128, "Sigma 24-105mm f/4 DG HSM | A"}, + {128, "Sigma 30mm f/1.4"}, + {128, "Sigma 35mm f/1.4 DG HSM | A"}, + {128, "Sigma 105mm f/2.8 EX DG OS HSM Macro"}, + {128, "Sigma 180mm f/2.8 EX DG OS HSM APO Macro"}, + {128, "Sigma 18-300mm f/3.5-6.3 DC Macro HSM | C"}, + {128, "Sigma 18-50mm f/2.8-4.5 DC HSM"}, {129, "Tamron Lens (129)"}, {129, "Tamron 200-400mm f/5.6 LD"}, {129, "Tamron 70-300mm f/4-5.6 LD"}, @@ -684,6 +690,8 @@ public: {213, "Tamron 16-300mm f/3.5-6.3 Di II PZD Macro"}, {214, "Tamron SP 150-600mm f/5-6.3 Di USD"}, {215, "Tamron SP 15-30mm f/2.8 Di USD"}, + {216, "Tamron SP 45mm f/1.8 Di USD"}, + {217, "Tamron SP 35mm f/1.8 Di USD"}, {218, "Tamron SP 90mm f/2.8 Di Macro 1:1 USD (F017)"}, {224, "Tamron SP 90mm f/2.8 Di Macro 1:1 USD (F004)"}, {255, "Tamron Lens (255)"}, @@ -838,6 +846,7 @@ public: {6553, "Sony E 20mm f/2.8"}, {6553, "Sony E 35mm f/1.8 OSS"}, {6553, "Sony E PZ 18-105mm f/4 G OSS"}, + {6553, "Sony FE 12-24mm f/4 G"}, {6553, "Sony FE 90mm f/2.8 Macro G OSS"}, {6553, "Sony E 18-50mm f/4-5.6"}, {6553, "Sony E PZ 18-200mm f/3.5-6.3 OSS"}, @@ -851,6 +860,7 @@ public: {6553, "Sony FE 28mm f/2"}, {6553, "Sony FE PZ 28-135mm f/4 G OSS"}, {6553, "Sony FE 100mm f/2.8 STF GM OSS"}, + {6553, "Sony E PZ 18-110mm f/4 G OSS"}, {6553, "Sony FE 24-70mm f/2.8 GM"}, {6553, "Sony FE 50mm f/1.4 ZA"}, {6553, "Sony FE 85mm f/1.4 GM"}, @@ -858,17 +868,27 @@ public: {6553, "Sony FE 21mm f/2.8 (SEL28F20 + SEL075UWC)"}, {6553, "Sony FE 16mm f/3.5 Fisheye (SEL28F20 + SEL057FEC)"}, {6553, "Sony FE 70-300mm f/4.5-5.6 G OSS"}, + {6553, "Sony FE 100-400mm f/4.5-5.6 GM OSS"}, {6553, "Sony FE 70-200mm f/2.8 GM OSS"}, + {6553, "Sony FE 16-35mm f/2.8 GM"}, {6553, "Sony FE 70-200mm f/2.8 GM OSS + 1.4X Teleconverter"}, {6553, "Sony FE 70-200mm f/2.8 GM OSS + 2X Teleconverter"}, + {6553, "Sony FE 100-400mm f/4.5-5.6 GM OSS + 1.4X Teleconverter"}, + {6553, "Sony FE 100-400mm f/4.5-5.6 GM OSS + 2X Teleconverter"}, {6553, "Samyang AF 50mm f/1.4 FE"}, {6553, "Samyang AF 14mm f/2.8 FE"}, + {6553, "Samyang AF 35mm f/2.8 FE"}, {6553, "Sigma 19mm f/2.8 [EX] DN"}, {6553, "Sigma 30mm f/2.8 [EX] DN"}, {6553, "Sigma 60mm f/2.8 DN"}, - {6553, "Sigma 30mm f/1.4 DC DN | C 016"}, + {6553, "Sigma 30mm f/1.4 DC DN | C"}, {6553, "Tamron 18-200mm f/3.5-6.3 Di III VC"}, {6553, "Tokina Firin 20mm f/2 FE MF"}, + {6553, "Voigtlander SUPER WIDE-HELIAR 15mm f/4.5 III"}, + {6553, "Voigtlander HELIAR-HYPER WIDE 10mm f/5.6"}, + {6553, "Voigtlander ULTRA WIDE-HELIAR 12mm f/5.6 III"}, + {6553, "Voigtlander MACRO APO-LANTHAR 65mm f/2 Aspherical"}, + {6553, "Voigtlander NOKTON 40mm f/1.2 Aspherical"}, {6553, "Zeiss Touit 12mm f/2.8"}, {6553, "Zeiss Touit 32mm f/1.8"}, {6553, "Zeiss Touit 50mm f/2.8 Macro"}, @@ -1029,6 +1049,7 @@ public: {65535, "Sony E 20mm f/2.8"}, {65535, "Sony E 35mm f/1.8 OSS"}, {65535, "Sony E PZ 18-105mm f/4 G OSS"}, + {65535, "Sony FE 12-24mm f/4 G"}, {65535, "Sony FE 90mm f/2.8 Macro G OSS"}, {65535, "Sony E 18-50mm f/4-5.6"}, {65535, "Sony E PZ 18-200mm f/3.5-6.3 OSS"}, @@ -1042,6 +1063,7 @@ public: {65535, "Sony FE 28mm f/2"}, {65535, "Sony FE PZ 28-135mm f/4 G OSS"}, {65535, "Sony FE 100mm f/2.8 STF GM OSS"}, + {65535, "Sony E PZ 18-110mm f/4 G OSS"}, {65535, "Sony FE 24-70mm f/2.8 GM"}, {65535, "Sony FE 50mm f/1.4 ZA"}, {65535, "Sony FE 85mm f/1.4 GM"}, @@ -1049,17 +1071,27 @@ public: {65535, "Sony FE 21mm f/2.8 (SEL28F20 + SEL075UWC)"}, {65535, "Sony FE 16mm f/3.5 Fisheye (SEL28F20 + SEL057FEC)"}, {65535, "Sony FE 70-300mm f/4.5-5.6 G OSS"}, + {65535, "Sony FE 100-400mm f/4.5-5.6 GM OSS"}, {65535, "Sony FE 70-200mm f/2.8 GM OSS"}, + {65535, "Sony FE 16-35mm f/2.8 GM"}, {65535, "Sony FE 70-200mm f/2.8 GM OSS + 1.4X Teleconverter"}, {65535, "Sony FE 70-200mm f/2.8 GM OSS + 2X Teleconverter"}, + {65535, "Sony FE 100-400mm f/4.5-5.6 GM OSS + 1.4X Teleconverter"}, + {65535, "Sony FE 100-400mm f/4.5-5.6 GM OSS + 2X Teleconverter"}, {65535, "Samyang AF 50mm f/1.4 FE"}, {65535, "Samyang AF 14mm f/2.8 FE"}, + {65535, "Samyang AF 35mm f/2.8 FE"}, {65535, "Sigma 19mm f/2.8 [EX] DN"}, {65535, "Sigma 30mm f/2.8 [EX] DN"}, {65535, "Sigma 60mm f/2.8 DN"}, - {65535, "Sigma 30mm f/1.4 DC DN | C 016"}, + {65535, "Sigma 30mm f/1.4 DC DN | C"}, {65535, "Tamron 18-200mm f/3.5-6.3 Di III VC"}, {65535, "Tokina Firin 20mm f/2 FE MF"}, + {65535, "Voigtlander SUPER WIDE-HELIAR 15mm f/4.5 III"}, + {65535, "Voigtlander HELIAR-HYPER WIDE 10mm f/5.6"}, + {65535, "Voigtlander ULTRA WIDE-HELIAR 12mm f/5.6 III"}, + {65535, "Voigtlander MACRO APO-LANTHAR 65mm f/2 Aspherical"}, + {65535, "Voigtlander NOKTON 40mm f/1.2 Aspherical"}, {65535, "Zeiss Touit 12mm f/2.8"}, {65535, "Zeiss Touit 32mm f/1.8"}, {65535, "Zeiss Touit 50mm f/2.8 Macro"}, @@ -1121,7 +1153,7 @@ public: SALensID2Interpreter () { choices.insert (p_t (0, "Unknown E-mount lens or other lens")); - choices.insert (p_t (1, "Sony LA-EA1 Adapter")); + choices.insert (p_t (1, "Sony LA-EA1 or Sigma MC-11 Adapter")); choices.insert (p_t (2, "Sony LA-EA2 Adapter")); choices.insert (p_t (3, "Sony LA-EA3 Adapter")); choices.insert (p_t (6, "Sony LA-EA4 Adapter")); @@ -1148,6 +1180,7 @@ public: choices.insert (p_t (32798, "Sony E 20mm f/2.8")); choices.insert (p_t (32799, "Sony E 35mm f/1.8 OSS")); choices.insert (p_t (32800, "Sony E PZ 18-105mm f/4 G OSS")); + choices.insert (p_t (32801, "Sony FE 12-24mm f/4 G")); choices.insert (p_t (32802, "Sony FE 90mm f/2.8 Macro G OSS")); choices.insert (p_t (32803, "Sony E 18-50mm f/4-5.6")); choices.insert (p_t (32807, "Sony E PZ 18-200mm f/3.5-6.3 OSS")); @@ -1161,6 +1194,7 @@ public: choices.insert (p_t (32816, "Sony FE 28mm f/2")); choices.insert (p_t (32817, "Sony FE PZ 28-135mm f/4 G OSS")); choices.insert (p_t (32819, "Sony FE 100mm f/2.8 STF GM OSS")); + choices.insert (p_t (32820, "Sony E PZ 18-110mm f/4 G OSS")); choices.insert (p_t (32821, "Sony FE 24-70mm f/2.8 GM")); choices.insert (p_t (32822, "Sony FE 50mm f/1.4 ZA")); choices.insert (p_t (32823, "Sony FE 85mm f/1.4 GM")); @@ -1168,11 +1202,15 @@ public: choices.insert (p_t (32826, "Sony FE 21mm f/2.8 (SEL28F20 + SEL075UWC)")); choices.insert (p_t (32827, "Sony FE 16mm f/3.5 Fisheye (SEL28F20 + SEL057FEC)")); choices.insert (p_t (32828, "Sony FE 70-300mm f/4.5-5.6 G OSS")); + choices.insert (p_t (32829, "Sony FE 100-400mm f/4.5-5.6 GM OSS")); choices.insert (p_t (32830, "Sony FE 70-200mm f/2.8 GM OSS")); - choices.insert (p_t (33002, "Sigma 85mm f/1.4 DG HSM | A 016 (+ Metabones Ver.50)")); + choices.insert (p_t (32831, "Sony FE 16-35mm f/2.8 GM")); + choices.insert (p_t (33002, "Sigma 85mm f/1.4 DG HSM | A (+ Metabones Ver.50)")); choices.insert (p_t (33072, "Sony FE 70-200mm f/2.8 GM OSS + 1.4X Teleconverter")); choices.insert (p_t (33073, "Sony FE 70-200mm f/2.8 GM OSS + 2X Teleconverter")); choices.insert (p_t (33076, "Sony FE 100mm f/2.8 STF GM OSS (macro mode)")); + choices.insert (p_t (33077, "Sony FE 100-400mm f/4.5-5.6 GM OSS + 1.4X Teleconverter")); + choices.insert (p_t (33078, "Sony FE 100-400mm f/4.5-5.6 GM OSS + 2X Teleconverter")); choices.insert (p_t (49201, "Zeiss Touit 12mm f/2.8")); choices.insert (p_t (49202, "Zeiss Touit 32mm f/1.8")); choices.insert (p_t (49203, "Zeiss Touit 50mm f/2.8 Macro")); @@ -1184,24 +1222,26 @@ public: choices.insert (p_t (49233, "Zeiss Loxia 35mm f/2")); choices.insert (p_t (49234, "Zeiss Loxia 21mm f/2.8")); choices.insert (p_t (49235, "Zeiss Loxia 85mm f/2.4")); - choices.insert (p_t (50480, "Sigma 30mm f/1.4 DC DN | C 016")); - choices.insert (p_t (50481, "Sigma 50mm f/1.4 DG HSM | A 014 + MC-11")); - choices.insert (p_t (50482, "Sigma 18-300mm f/3.5-6.3 DC MACRO OS HSM | C 014 + MC-11")); - choices.insert (p_t (50483, "Sigma 18-35mm f/1.8 DC HSM | A 013 + MC-11")); - choices.insert (p_t (50484, "Sigma 24-35mm f/2 DG HSM | A 015 + MC-11")); - choices.insert (p_t (50486, "Sigma 150-600mm f/5-6.3 DG OS HSM | C 015 + MC-11")); - choices.insert (p_t (50487, "Sigma 20mm f/1.4 DG HSM | A 015 + MC-11")); - choices.insert (p_t (50488, "Sigma 35mm f/1.4 DG HSM | A 012 + MC-11")); - choices.insert (p_t (50489, "Sigma 150-600mm f/5-6.3 DG OS HSM | S 014 + MC-11")); - choices.insert (p_t (50490, "Sigma 120-300mm f/2.8 DG OS HSM | S 013 + MC-11")); - choices.insert (p_t (50492, "Sigma 24-105mm f/4 DG OS HSM | A 013 + MC-11")); - choices.insert (p_t (50493, "Sigma 17-70mm f/2.8-4 DC MACRO OS HSM | C 013 + MC-11")); - choices.insert (p_t (50495, "Sigma 50-100mm f/1.8 DC HSM | A 016 + MC-11")); + choices.insert (p_t (50480, "Sigma 30mm f/1.4 DC DN | C")); + choices.insert (p_t (50481, "Sigma 50mm f/1.4 DG HSM | A + MC-11")); + choices.insert (p_t (50482, "Sigma 18-300mm f/3.5-6.3 DC MACRO OS HSM | C + MC-11")); + choices.insert (p_t (50483, "Sigma 18-35mm f/1.8 DC HSM | A + MC-11")); + choices.insert (p_t (50484, "Sigma 24-35mm f/2 DG HSM | A + MC-11")); + choices.insert (p_t (50486, "Sigma 150-600mm f/5-6.3 DG OS HSM | C + MC-11")); + choices.insert (p_t (50487, "Sigma 20mm f/1.4 DG HSM | A + MC-11")); + choices.insert (p_t (50488, "Sigma 35mm f/1.4 DG HSM | A + MC-11")); + choices.insert (p_t (50489, "Sigma 150-600mm f/5-6.3 DG OS HSM | S + MC-11")); + choices.insert (p_t (50490, "Sigma 120-300mm f/2.8 DG OS HSM | S + MC-11")); + choices.insert (p_t (50492, "Sigma 24-105mm f/4 DG OS HSM | A + MC-11")); + choices.insert (p_t (50493, "Sigma 17-70mm f/2.8-4 DC MACRO OS HSM | C + MC-11")); + choices.insert (p_t (50495, "Sigma 50-100mm f/1.8 DC HSM | A + MC-11")); 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")); + choices.insert (p_t (50995, "Voigtlander MACRO APO-LANTHAR 65mm f/2 Aspherical")); choices.insert (p_t (50996, "Voigtlander NOKTON 40mm f/1.2 Aspherical")); - choices.insert (p_t (51505, "Samyang AF 14mm f/2.8 FE")); + choices.insert (p_t (51505, "Samyang AF 14mm f/2.8 FE or Samyang AF 35mm f/2.8 FE")); + choices.insert (p_t (51505, "Samyang AF 35mm f/2.8 FE")); } virtual std::string toString (Tag* t) @@ -2010,7 +2050,7 @@ public: return "n/a"; } } - virtual double toDouble (Tag* t, int ofs) + virtual double toDouble (const Tag* t, int ofs) { // Get the value; Depending on the camera model, this parameter can be a BYTE or a SHORT TagType astype = t->getType(); @@ -2029,7 +2069,7 @@ public: return 0.; } } - virtual int toInt (Tag* t, int ofs, TagType astype) + virtual int toInt (const Tag* t, int ofs, TagType astype) { // Get the value; Depending on the camera model, this parameter can be a BYTE or a SHORT int a = 0; @@ -2070,7 +2110,7 @@ public: return "n/a"; } } - virtual double toDouble (Tag* t, int ofs) + virtual double toDouble (const Tag* t, int ofs) { // Get the value; Depending on the camera model, this parameter can be a BYTE or a SHORT TagType astype = t->getType(); @@ -2089,7 +2129,7 @@ public: return 0.; } } - virtual int toInt (Tag* t, int ofs, TagType astype) + virtual int toInt (const Tag* t, int ofs, TagType astype) { // Get the value; Depending on the camera model, this parameter can be a BYTE or a SHORT int a = 0; @@ -2130,7 +2170,7 @@ public: return "Auto"; } } - virtual int toInt (Tag* t, int ofs, TagType astype) + virtual int toInt (const Tag* t, int ofs, TagType astype) { // Get the value; Depending on the camera model, this parameter can be a BYTE or a SHORT int a = 0; @@ -2166,7 +2206,7 @@ public: sprintf (buffer, "%.2f", a ); return buffer; } - virtual double toDouble (Tag* t, int ofs) + virtual double toDouble (const Tag* t, int ofs) { // Get the value int a = t->getValue()[ofs]; @@ -2186,7 +2226,7 @@ public: sprintf (buffer, "%d", t->getValue()[0] - 20); return buffer; } - virtual int toInt (Tag* t, int ofs, TagType astype) + virtual int toInt (const Tag* t, int ofs, TagType astype) { return t->getValue()[0] - 20; } @@ -2207,7 +2247,7 @@ public: return "Off"; } - virtual int toInt (Tag* t, int ofs, TagType astype) + virtual int toInt (const Tag* t, int ofs, TagType astype) { return (t->getValue()[0] & 0x80) == 0x80 ? 1 : 0; } @@ -2225,7 +2265,7 @@ public: sprintf (buffer, "%d", t->getValue()[0] & 0x7f); return buffer; } - virtual int toInt (Tag* t, int ofs, TagType astype) + virtual int toInt (const Tag* t, int ofs, TagType astype) { return t->getValue()[0] & 0x7f; } @@ -2281,7 +2321,7 @@ public: sprintf (buffer, "%d", t->toInt()); return buffer; } - virtual int toInt (Tag* t, int ofs, TagType astype) + virtual int toInt (const Tag* t, int ofs, TagType astype) { int a = 0; diff --git a/rtexif/stdattribs.cc b/rtexif/stdattribs.cc index 514dd5215..a7e3fe00f 100644 --- a/rtexif/stdattribs.cc +++ b/rtexif/stdattribs.cc @@ -534,11 +534,28 @@ public: }; UTF8BinInterpreter utf8BinInterpreter; +class RawImageSegmentationInterpreter : public Interpreter +{ +public: + virtual std::string toString (Tag* t) + { + int segmentNumber = t->toInt(0, SHORT); + int segmentWidth = t->toInt(2, SHORT); + int lastSegmentWidth = t->toInt(4, SHORT); + + char buffer[32]; + sprintf (buffer, "%d %d %d", segmentNumber, segmentWidth, lastSegmentWidth); + return buffer; + } +}; +RawImageSegmentationInterpreter rawImageSegmentationInterpreter; + const TagAttrib exifAttribs[] = { {0, AC_SYSTEM, 0, nullptr, 0x0100, AUTO, "ImageWidth", &stdInterpreter}, {0, AC_SYSTEM, 0, nullptr, 0x0101, AUTO, "ImageHeight", &stdInterpreter}, {0, AC_SYSTEM, 0, nullptr, 0x0102, AUTO, "BitsPerSample", &stdInterpreter}, {0, AC_SYSTEM, 0, nullptr, 0x0103, AUTO, "Compression", &compressionInterpreter}, + {0, AC_SYSTEM, 0, nullptr, 0x0153, AUTO, "SampleFormat", &stdInterpreter}, {0, AC_WRITE, 0, nullptr, 0x828d, AUTO, "CFAPatternDim", &stdInterpreter}, {0, AC_WRITE, 0, nullptr, 0x828e, AUTO, "CFAPattern", &cfaInterpreter}, {0, AC_WRITE, 0, nullptr, 0x829A, AUTO, "ExposureTime", &exposureTimeInterpreter}, @@ -643,9 +660,9 @@ const TagAttrib exifAttribs[] = { {0, AC_WRITE, 0, nullptr, 0xC68B, AUTO, "OriginalRawFileName", &stdInterpreter}, {0, AC_WRITE, 0, nullptr, 0xC68D, AUTO, "ActiveArea", &stdInterpreter}, {0, AC_WRITE, 0, nullptr, 0xC68E, AUTO, "MaskedAreas", &stdInterpreter}, -// {0, AC_WRITE, 0, 0, 0xC68F, AUTO, "AsShotICCProfile", & ???}, +// {0, AC_WRITE, 0, nullptr, 0xC68F, AUTO, "AsShotICCProfile", & ???}, {0, AC_WRITE, 0, nullptr, 0xC690, AUTO, "AsShotPreProfileMatrix", &stdInterpreter}, -// {0, AC_WRITE, 0, 0, 0xC691, AUTO, "CurrentICCProfile", & ???}, +// {0, AC_WRITE, 0, nullptr, 0xC691, AUTO, "CurrentICCProfile", & ???}, {0, AC_WRITE, 0, nullptr, 0xC692, AUTO, "CurrentPreProfileMatrix", &stdInterpreter}, {0, AC_WRITE, 0, nullptr, 0xC6BF, AUTO, "ColorimetricReference", &stdInterpreter}, {0, AC_WRITE, 0, nullptr, 0xC6F3, AUTO, "CameraCalibrationSig", &stdInterpreter}, @@ -670,13 +687,13 @@ const TagAttrib exifAttribs[] = { {0, AC_WRITE, 0, nullptr, 0xC71B, AUTO, "PreviewDateTime", &stdInterpreter}, {0, AC_WRITE, 0, nullptr, 0xC71C, AUTO, "RawImageDigest", &stdInterpreter}, {0, AC_WRITE, 0, nullptr, 0xC71D, AUTO, "OriginalRawFileDigest", &stdInterpreter}, -// {0, AC_WRITE, 0, 0, 0xC71E, AUTO, "SubTileBlockSize", & ???}, -// {0, AC_WRITE, 0, 0, 0xC71F, AUTO, "RowInterleaveFactor", & ???}, +// {0, AC_WRITE, 0, nullptr, 0xC71E, AUTO, "SubTileBlockSize", & ???}, +// {0, AC_WRITE, 0, nullptr, 0xC71F, AUTO, "RowInterleaveFactor", & ???}, {0, AC_WRITE, 0, nullptr, 0xC725, AUTO, "ProfileLookTableDims", &stdInterpreter}, {0, AC_WRITE, 0, nullptr, 0xC726, AUTO, "ProfileLookTableData", &stdInterpreter}, -// {0, AC_WRITE, 0, 0, 0xC740, AUTO, "OpcodeList1", & ???}, -// {0, AC_WRITE, 0, 0, 0xC741, AUTO, "OpcodeList2", & ???}, -// {0, AC_WRITE, 0, 0, 0xC74E, AUTO, "OpcodeList3", & ???}, +// {0, AC_WRITE, 0, nullptr, 0xC740, AUTO, "OpcodeList1", & ???}, +// {0, AC_WRITE, 0, nullptr, 0xC741, AUTO, "OpcodeList2", & ???}, +// {0, AC_WRITE, 0, nullptr, 0xC74E, AUTO, "OpcodeList3", & ???}, {0, AC_WRITE, 0, nullptr, 0xC761, AUTO, "NoiseProfile", &stdInterpreter}, {0, AC_WRITE, 0, nullptr, 0xC763, AUTO, "TimeCodes", &stdInterpreter}, {0, AC_WRITE, 0, nullptr, 0xC764, AUTO, "FrameRate", &stdInterpreter}, @@ -753,6 +770,7 @@ const TagAttrib iopAttribs[] = { const TagAttrib ifdAttribs[] = { {0, AC_SYSTEM, 0, nullptr, 0x0017, AUTO, "PanaISO", &stdInterpreter}, + {0, AC_SYSTEM, 0, nullptr, 0x00fe, AUTO, "NewSubFileType", &stdInterpreter}, {0, AC_SYSTEM, 0, nullptr, 0x0100, AUTO, "ImageWidth", &stdInterpreter}, {0, AC_SYSTEM, 0, nullptr, 0x0101, AUTO, "ImageHeight", &stdInterpreter}, {0, AC_SYSTEM, 0, nullptr, 0x0102, AUTO, "BitsPerSample", &stdInterpreter}, @@ -777,6 +795,7 @@ const TagAttrib ifdAttribs[] = { {0, AC_SYSTEM, 0, nullptr, 0x013E, AUTO, "WhitePoint", &stdInterpreter}, {0, AC_SYSTEM, 0, nullptr, 0x013F, AUTO, "PriomaryChromaticities", &stdInterpreter}, {0, AC_WRITE, 0, ifdAttribs, 0x014A, AUTO, "SubIFD", &stdInterpreter}, + {0, AC_SYSTEM, 0, nullptr, 0x0153, AUTO, "SampleFormat", &stdInterpreter}, {0, AC_SYSTEM, 0, nullptr, 0x0201, AUTO, "JPEGInterchangeFormat", &stdInterpreter}, {0, AC_SYSTEM, 0, nullptr, 0x0202, AUTO, "JPEGInterchangeFormatLength", &stdInterpreter}, {0, AC_SYSTEM, 0, nullptr, 0x0211, AUTO, "YCbCrCoefficients", &stdInterpreter}, @@ -807,9 +826,9 @@ const TagAttrib ifdAttribs[] = { {0, AC_WRITE, 0, nullptr, 0xc62f, AUTO, "CameraSerialNumber", &stdInterpreter}, {0, AC_SYSTEM, 0, nullptr, 0xc630, AUTO, "DNGLensInfo", &stdInterpreter}, {0, AC_DONTWRITE, 0, nullptr, 0xC634, AUTO, "MakerNote", &stdInterpreter}, //DNGPrivateData + {0, AC_SYSTEM, 0, nullptr, 0xC640, AUTO, "RawImageSegmentation", &rawImageSegmentationInterpreter}, {0, AC_WRITE, 0, nullptr, 0xc65d, AUTO, "RawDataUniqueID", &stdInterpreter}, {0, AC_DONTWRITE, 0, nullptr, 0xc761, AUTO, "NoiseProfile", &stdInterpreter}, - {0, AC_SYSTEM, 0, nullptr, 0x00fe, AUTO, "NewSubFileType", &stdInterpreter}, { -1, AC_DONTWRITE, 0, nullptr, 0, AUTO, "", nullptr} }; } diff --git a/rtgui/CMakeLists.txt b/rtgui/CMakeLists.txt index 2a6f6df49..090e9e867 100644 --- a/rtgui/CMakeLists.txt +++ b/rtgui/CMakeLists.txt @@ -1,278 +1,285 @@ -# Common source files for both CLI and non-CLI execautables -set(CLISOURCEFILES - edit.cc - main-cli.cc - multilangmgr.cc - options.cc - paramsedited.cc - pathutils.cc - threadutils.cc - ) - -set(NONCLISOURCEFILES - adjuster.cc - batchqueue.cc - batchqueuebuttonset.cc - batchqueueentry.cc - batchqueuepanel.cc - batchtoolpanelcoord.cc - bayerpreprocess.cc - bayerprocess.cc - bayerrawexposure.cc - blackwhite.cc - bqentryupdater.cc - browserfilter.cc - cacheimagedata.cc - cachemanager.cc - cacorrection.cc - checkbox.cc - chmixer.cc - clipboard.cc - coarsepanel.cc - colorappearance.cc - coloredbar.cc - colortoning.cc - coordinateadjuster.cc - crop.cc - crophandler.cc - cropwindow.cc - cursormanager.cc - curveeditor.cc - curveeditorgroup.cc - darkframe.cc - defringe.cc - diagonalcurveeditorsubgroup.cc - dirbrowser.cc - dirpyrdenoise.cc - dirpyrequalizer.cc - distortion.cc - dynamicprofilepanel.cc - edit.cc - editorpanel.cc - editwindow.cc - epd.cc - exiffiltersettings.cc - exifpanel.cc - exportpanel.cc - extprog.cc - filebrowser.cc - filebrowserentry.cc - filecatalog.cc - filepanel.cc - filethumbnailbuttonset.cc - filmsimulation.cc - filterpanel.cc - flatcurveeditorsubgroup.cc - flatfield.cc - gradient.cc - guiutils.cc - histogrampanel.cc - history.cc - hsvequalizer.cc - icmpanel.cc - ilabel.cc - imagearea.cc - imageareapanel.cc - impulsedenoise.cc - indclippedpanel.cc - inspector.cc - iptcpanel.cc - labcurve.cc - lensgeom.cc - lensprofile.cc - lockablecolorpicker.cc - lwbutton.cc - lwbuttonset.cc - main.cc - multilangmgr.cc - mycurve.cc - mydiagonalcurve.cc - myflatcurve.cc - navigator.cc - options.cc - paramsedited.cc - partialpastedlg.cc - pathutils.cc - pcvignette.cc - perspective.cc - placesbrowser.cc - popupbutton.cc - popupcommon.cc - popuptogglebutton.cc - preferences.cc - preprocess.cc - previewhandler.cc - previewloader.cc - previewmodepanel.cc - previewwindow.cc - profilepanel.cc - profilestorecombobox.cc - prsharpening.cc - rawcacorrection.cc - rawexposure.cc - recentbrowser.cc - renamedlg.cc - resize.cc - retinex.cc - rgbcurves.cc - rotate.cc - rtimage.cc - rtwindow.cc - saveasdlg.cc - saveformatpanel.cc - sensorbayer.cc - sensorxtrans.cc - shadowshighlights.cc - sharpenedge.cc - sharpening.cc - sharpenmicro.cc - shcselector.cc - soundman.cc - splash.cc - spot.cc - threadutils.cc - thresholdadjuster.cc - thresholdselector.cc - thumbbrowserbase.cc - thumbbrowserentrybase.cc - thumbimageupdater.cc - thumbnail.cc - tonecurve.cc - toolbar.cc - toolpanel.cc - toolpanelcoord.cc - vibrance.cc - vignetting.cc - wavelet.cc - whitebalance.cc - xtransprocess.cc - xtransrawexposure.cc - zoompanel.cc - ) - -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}) -endif() - -if(WIN32) - set(EXTRA_SRC_CLI myicon.rc) - set(EXTRA_SRC_NONCLI myicon.rc windirmonitor.cc) - set(EXTRA_LIB_RTGUI winmm) - include_directories(${EXTRA_INCDIR} - ${GIOMM_INCLUDE_DIRS} - ${GIO_INCLUDE_DIRS} - ${GLIB2_INCLUDE_DIRS} - ${GLIBMM_INCLUDE_DIRS} - ${GTKMM_INCLUDE_DIRS} - ${GTK_INCLUDE_DIRS} - ) - link_directories(. "${PROJECT_SOURCE_DIR}/rtexif" - ${EXTRA_LIBDIR} - ${GIOMM_LIBRARY_DIRS} - ${GIO_LIBRARY_DIRS} - ${GLIB2_LIBRARY_DIRS} - ${GLIBMM_LIBRARY_DIRS} - ${GTKMM_LIBRARY_DIRS} - ${GTK_LIBRARY_DIRS} - ) -else() - include_directories(${EXTRA_INCDIR} - ${CANBERRA-GTK_INCLUDE_DIRS} - ${EXPAT_INCLUDE_DIRS} - ${FFTW3F_LIBRARY_DIRS} - ${GIOMM_INCLUDE_DIRS} - ${GIO_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} - ) - link_directories(${EXTRA_LIBDIR} - ${CANBERRA-GTK_LIBRARY_DIRS} - ${EXPAT_LIBRARY_DIRS} - ${FFTW3F_LIBRARY_DIRS} - ${GIOMM_LIBRARY_DIRS} - ${GIO_LIBRARY_DIRS} - ${GLIB2_LIBRARY_DIRS} - ${GLIBMM_LIBRARY_DIRS} - ${GOBJECT_LIBRARY_DIRS} - ${GTHREAD_LIBRARY_DIRS} - ${GTKMM_LIBRARY_DIRS} - ${GTK_LIBRARY_DIRS} - ${IPTCDATA_LIBRARY_DIRS} - ${LCMS_LIBRARY_DIRS} - ) -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 dependencies to executables targets -add_dependencies(rth UpdateInfo) -add_dependencies(rth-cli UpdateInfo) - -# Set executables targets properties, i.e. output filename and compile flags -# for "Debug" builds, open a console in all cases for Windows version -if((WIN32) AND NOT(UPPER_CMAKE_BUILD_TYPE STREQUAL "DEBUG")) - set_target_properties(rth PROPERTIES LINK_FLAGS "-mwindows") -endif() -set_target_properties(rth PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS}" OUTPUT_NAME rawtherapee) -set_target_properties(rth-cli PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS} -DRAWTHERAPEE_CLI" OUTPUT_NAME rawtherapee-cli) - -# Add linked libraries dependencies to executables targets -target_link_libraries(rth rtengine - ${CANBERRA-GTK_LIBRARIES} - ${EXPAT_LIBRARIES} - ${EXTRA_LIB_RTGUI} - ${FFTW3F_LIBRARIES} - ${GIOMM_LIBRARIES} - ${GIO_LIBRARIES} - ${GLIB2_LIBRARIES} - ${GLIBMM_LIBRARIES} - ${GOBJECT_LIBRARIES} - ${GTHREAD_LIBRARIES} - ${GTKMM_LIBRARIES} - ${GTK_LIBRARIES} - ${IPTCDATA_LIBRARIES} - ${JPEG_LIBRARIES} - ${LCMS_LIBRARIES} - ${PNG_LIBRARIES} - ${TIFF_LIBRARIES} - ${ZLIB_LIBRARIES} - ) - -target_link_libraries(rth-cli rtengine - ${CAIROMM_LIBRARIES} - ${EXPAT_LIBRARIES} - ${EXTRA_LIB_RTGUI} - ${FFTW3F_LIBRARIES} - ${GIOMM_LIBRARIES} - ${GIO_LIBRARIES} - ${GLIB2_LIBRARIES} - ${GLIBMM_LIBRARIES} - ${GOBJECT_LIBRARIES} - ${GTHREAD_LIBRARIES} - ${IPTCDATA_LIBRARIES} - ${JPEG_LIBRARIES} - ${LCMS_LIBRARIES} - ${PNG_LIBRARIES} - ${TIFF_LIBRARIES} - ${ZLIB_LIBRARIES} - ) - -# Install executables -install(TARGETS rth DESTINATION ${BINDIR}) -install(TARGETS rth-cli DESTINATION ${BINDIR}) +# Common source files for both CLI and non-CLI execautables +set(CLISOURCEFILES + edit.cc + main-cli.cc + multilangmgr.cc + options.cc + paramsedited.cc + pathutils.cc + threadutils.cc + ) + +set(NONCLISOURCEFILES + adjuster.cc + batchqueue.cc + batchqueuebuttonset.cc + batchqueueentry.cc + batchqueuepanel.cc + batchtoolpanelcoord.cc + bayerpreprocess.cc + bayerprocess.cc + bayerrawexposure.cc + blackwhite.cc + bqentryupdater.cc + browserfilter.cc + cacheimagedata.cc + cachemanager.cc + cacorrection.cc + checkbox.cc + chmixer.cc + clipboard.cc + coarsepanel.cc + colorappearance.cc + coloredbar.cc + colortoning.cc + coordinateadjuster.cc + crop.cc + crophandler.cc + cropwindow.cc + cursormanager.cc + curveeditor.cc + curveeditorgroup.cc + darkframe.cc + defringe.cc + diagonalcurveeditorsubgroup.cc + dirbrowser.cc + dirpyrdenoise.cc + dirpyrequalizer.cc + distortion.cc + dynamicprofilepanel.cc + edit.cc + editorpanel.cc + editwindow.cc + epd.cc + exiffiltersettings.cc + exifpanel.cc + exportpanel.cc + extprog.cc + filebrowser.cc + filebrowserentry.cc + filecatalog.cc + filepanel.cc + filethumbnailbuttonset.cc + filmsimulation.cc + filterpanel.cc + flatcurveeditorsubgroup.cc + flatfield.cc + gradient.cc + guiutils.cc + histogrampanel.cc + history.cc + hsvequalizer.cc + icmpanel.cc + ilabel.cc + imagearea.cc + imageareapanel.cc + impulsedenoise.cc + indclippedpanel.cc + inspector.cc + iptcpanel.cc + labcurve.cc + lensgeom.cc + lensprofile.cc + lockablecolorpicker.cc + lwbutton.cc + lwbuttonset.cc + main.cc + multilangmgr.cc + mycurve.cc + mydiagonalcurve.cc + myflatcurve.cc + navigator.cc + options.cc + paramsedited.cc + partialpastedlg.cc + pathutils.cc + pcvignette.cc + perspective.cc + placesbrowser.cc + popupbutton.cc + popupcommon.cc + popuptogglebutton.cc + preferences.cc + preprocess.cc + previewhandler.cc + previewloader.cc + previewmodepanel.cc + previewwindow.cc + profilepanel.cc + profilestorecombobox.cc + prsharpening.cc + rawcacorrection.cc + rawexposure.cc + recentbrowser.cc + renamedlg.cc + resize.cc + retinex.cc + rgbcurves.cc + rotate.cc + rtimage.cc + rtwindow.cc + saveasdlg.cc + saveformatpanel.cc + sensorbayer.cc + sensorxtrans.cc + shadowshighlights.cc + sharpenedge.cc + sharpening.cc + sharpenmicro.cc + shcselector.cc + soundman.cc + splash.cc + spot.cc + threadutils.cc + thresholdadjuster.cc + thresholdselector.cc + thumbbrowserbase.cc + thumbbrowserentrybase.cc + thumbimageupdater.cc + thumbnail.cc + tonecurve.cc + toolbar.cc + toolpanel.cc + toolpanelcoord.cc + vibrance.cc + vignetting.cc + wavelet.cc + whitebalance.cc + xtransprocess.cc + xtransrawexposure.cc + zoompanel.cc + fattaltonemap.cc + ) + +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}) +endif() + +if(WIN32) + set(EXTRA_SRC_CLI myicon.rc) + set(EXTRA_SRC_NONCLI myicon.rc windirmonitor.cc) + set(EXTRA_LIB_RTGUI winmm) + include_directories(${EXTRA_INCDIR} + ${GIOMM_INCLUDE_DIRS} + ${GIO_INCLUDE_DIRS} + ${GLIB2_INCLUDE_DIRS} + ${GLIBMM_INCLUDE_DIRS} + ${GTKMM_INCLUDE_DIRS} + ${GTK_INCLUDE_DIRS} + ${LENSFUN_INCLUDE_DIRS} + ) + link_directories(. "${PROJECT_SOURCE_DIR}/rtexif" + ${EXTRA_LIBDIR} + ${GIOMM_LIBRARY_DIRS} + ${GIO_LIBRARY_DIRS} + ${GLIB2_LIBRARY_DIRS} + ${GLIBMM_LIBRARY_DIRS} + ${GTKMM_LIBRARY_DIRS} + ${GTK_LIBRARY_DIRS} + ${LENSFUN_LIBRARY_DIRS} + ) +else() + include_directories(${EXTRA_INCDIR} + ${CANBERRA-GTK_INCLUDE_DIRS} + ${EXPAT_INCLUDE_DIRS} + ${FFTW3F_LIBRARY_DIRS} + ${GIOMM_INCLUDE_DIRS} + ${GIO_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} + ) + link_directories(${EXTRA_LIBDIR} + ${CANBERRA-GTK_LIBRARY_DIRS} + ${EXPAT_LIBRARY_DIRS} + ${FFTW3F_LIBRARY_DIRS} + ${GIOMM_LIBRARY_DIRS} + ${GIO_LIBRARY_DIRS} + ${GLIB2_LIBRARY_DIRS} + ${GLIBMM_LIBRARY_DIRS} + ${GOBJECT_LIBRARY_DIRS} + ${GTHREAD_LIBRARY_DIRS} + ${GTKMM_LIBRARY_DIRS} + ${GTK_LIBRARY_DIRS} + ${IPTCDATA_LIBRARY_DIRS} + ${LCMS_LIBRARY_DIRS} + ${LENSFUN_LIBRARY_DIRS} + ) +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 dependencies to executables targets +add_dependencies(rth UpdateInfo) +add_dependencies(rth-cli UpdateInfo) + +# Set executables targets properties, i.e. output filename and compile flags +# for "Debug" builds, open a console in all cases for Windows version +if((WIN32) AND NOT(UPPER_CMAKE_BUILD_TYPE STREQUAL "DEBUG")) + set_target_properties(rth PROPERTIES LINK_FLAGS "-mwindows") +endif() +set_target_properties(rth PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS}" OUTPUT_NAME rawtherapee) +set_target_properties(rth-cli PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS}" OUTPUT_NAME rawtherapee-cli) + +# Add linked libraries dependencies to executables targets +target_link_libraries(rth rtengine + ${CANBERRA-GTK_LIBRARIES} + ${EXPAT_LIBRARIES} + ${EXTRA_LIB_RTGUI} + ${FFTW3F_LIBRARIES} + ${GIOMM_LIBRARIES} + ${GIO_LIBRARIES} + ${GLIB2_LIBRARIES} + ${GLIBMM_LIBRARIES} + ${GOBJECT_LIBRARIES} + ${GTHREAD_LIBRARIES} + ${GTKMM_LIBRARIES} + ${GTK_LIBRARIES} + ${IPTCDATA_LIBRARIES} + ${JPEG_LIBRARIES} + ${LCMS_LIBRARIES} + ${PNG_LIBRARIES} + ${TIFF_LIBRARIES} + ${ZLIB_LIBRARIES} + ${LENSFUN_LIBRARIES} + ) + +target_link_libraries(rth-cli rtengine + ${CAIROMM_LIBRARIES} + ${EXPAT_LIBRARIES} + ${EXTRA_LIB_RTGUI} + ${FFTW3F_LIBRARIES} + ${GIOMM_LIBRARIES} + ${GIO_LIBRARIES} + ${GLIB2_LIBRARIES} + ${GLIBMM_LIBRARIES} + ${GOBJECT_LIBRARIES} + ${GTHREAD_LIBRARIES} + ${IPTCDATA_LIBRARIES} + ${JPEG_LIBRARIES} + ${LCMS_LIBRARIES} + ${PNG_LIBRARIES} + ${TIFF_LIBRARIES} + ${ZLIB_LIBRARIES} + ${LENSFUN_LIBRARIES} + ) + +# Install executables +install(TARGETS rth DESTINATION ${BINDIR}) +install(TARGETS rth-cli DESTINATION ${BINDIR}) diff --git a/rtgui/addsetids.h b/rtgui/addsetids.h index 898ef9528..07cf47d18 100644 --- a/rtgui/addsetids.h +++ b/rtgui/addsetids.h @@ -116,6 +116,19 @@ enum { ADDSET_RETI_GAM, ADDSET_RETI_SLO, ADDSET_WB_TEMPBIAS, + ADDSET_SHARP_RADIUS, + ADDSET_SHARP_DAMPING, + ADDSET_SHARP_ITER, + ADDSET_SHARP_EDGETOL, + ADDSET_SHARP_HALOCTRL, + ADDSET_RESIZE_SCALE, + ADDSET_EPD_STRENGTH, + ADDSET_EPD_GAMMA, + ADDSET_EPD_EDGESTOPPING, + ADDSET_EPD_SCALE, + ADDSET_EPD_REWEIGHTINGITERATES, + ADDSET_FATTAL_ALPHA, + ADDSET_FATTAL_BETA, ADDSET_PARAM_NUM // THIS IS USED AS A DELIMITER!! }; diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc index da042347d..43ee5d79d 100644 --- a/rtgui/batchqueue.cc +++ b/rtgui/batchqueue.cc @@ -245,10 +245,10 @@ bool BatchQueue::saveBatchQueue () file << entry->filename << '|' << entry->savedParamsFile << '|' << entry->outFileName << '|' << saveFormat.format << '|' #endif << saveFormat.jpegQuality << '|' << saveFormat.jpegSubSamp << '|' - << saveFormat.pngBits << '|' << saveFormat.pngCompression << '|' + << saveFormat.pngBits << '|' << saveFormat.tiffBits << '|' << saveFormat.tiffUncompressed << '|' << saveFormat.saveParams << '|' << entry->forceFormatOpts << '|' - << entry->job->fastPipeline() << '|' + << entry->fast_pipeline << '|' << std::endl; } } @@ -310,7 +310,6 @@ bool BatchQueue::loadBatchQueue () const auto jpegQuality = nextIntOr (options.saveFormat.jpegQuality); const auto jpegSubSamp = nextIntOr (options.saveFormat.jpegSubSamp); const auto pngBits = nextIntOr (options.saveFormat.pngBits); - const auto pngCompression = nextIntOr (options.saveFormat.pngCompression); const auto tiffBits = nextIntOr (options.saveFormat.tiffBits); const auto tiffUncompressed = nextIntOr (options.saveFormat.tiffUncompressed); const auto saveParams = nextIntOr (options.saveFormat.saveParams); @@ -352,7 +351,6 @@ bool BatchQueue::loadBatchQueue () saveFormat.jpegQuality = jpegQuality; saveFormat.jpegSubSamp = jpegSubSamp; saveFormat.pngBits = pngBits; - saveFormat.pngCompression = pngCompression; saveFormat.tiffBits = tiffBits; saveFormat.tiffUncompressed = tiffUncompressed != 0; saveFormat.saveParams = saveParams != 0; @@ -612,7 +610,7 @@ rtengine::ProcessingJob* BatchQueue::imageReady (rtengine::IImage16* img) if (saveFormat.format == "tif") { err = img->saveAsTIFF (fname, saveFormat.tiffBits, saveFormat.tiffUncompressed); } else if (saveFormat.format == "png") { - err = img->saveAsPNG (fname, saveFormat.pngCompression, saveFormat.pngBits); + err = img->saveAsPNG (fname, saveFormat.pngBits); } else if (saveFormat.format == "jpg") { err = img->saveAsJPEG (fname, saveFormat.jpegQuality, saveFormat.jpegSubSamp); } @@ -743,8 +741,14 @@ Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileNam da.push_back (tok); } - if (origFileName[0] == '/' || origFileName[0] == '\\') { + if (origFileName[0] == '/') { pa.push_back ("/" + da[0]); + } else if (origFileName[0] == '\\') { + if (origFileName.size() > 1 && origFileName[1] == '\\') { + pa.push_back ("\\\\" + da[0]); + } else { + pa.push_back ("/" + da[0]); + } } else { pa.push_back (da[0]); } diff --git a/rtgui/batchqueueentry.cc b/rtgui/batchqueueentry.cc index 8386a8ee6..3092d6db4 100644 --- a/rtgui/batchqueueentry.cc +++ b/rtgui/batchqueueentry.cc @@ -29,10 +29,19 @@ bool BatchQueueEntry::iconsLoaded(false); Glib::RefPtr BatchQueueEntry::savedAsIcon; -BatchQueueEntry::BatchQueueEntry (rtengine::ProcessingJob* pjob, const rtengine::procparams::ProcParams& pparams, Glib::ustring fname, int prevw, int prevh, Thumbnail* thm) - : ThumbBrowserEntryBase(fname), - opreview(nullptr), origpw(prevw), origph(prevh), opreviewDone(false), - job(pjob), params(pparams), progress(0), outFileName(""), sequence(0), forceFormatOpts(false) +BatchQueueEntry::BatchQueueEntry (rtengine::ProcessingJob* pjob, const rtengine::procparams::ProcParams& pparams, Glib::ustring fname, int prevw, int prevh, Thumbnail* thm) : + ThumbBrowserEntryBase(fname), + opreview(nullptr), + origpw(prevw), + origph(prevh), + opreviewDone(false), + job(pjob), + params(pparams), + progress(0), + outFileName(""), + sequence(0), + forceFormatOpts(false), + fast_pipeline(job->fastPipeline()) { thumbnail = thm; @@ -177,8 +186,6 @@ Glib::ustring BatchQueueEntry::getToolTip (int x, int y) saveFormat.jpegSubSamp == 1 ? M("SAVEDLG_SUBSAMP_1") : saveFormat.jpegSubSamp == 2 ? M("SAVEDLG_SUBSAMP_2") : M("SAVEDLG_SUBSAMP_3")); - } else if (saveFormat.format == "png") { - tooltip += Glib::ustring::compose("\n%1: %2", M("SAVEDLG_PNGCOMPR"), saveFormat.pngCompression); } else if (saveFormat.format == "tif") { if (saveFormat.tiffUncompressed) { tooltip += Glib::ustring::compose("\n%1", M("SAVEDLG_TIFFUNCOMPRESSED")); diff --git a/rtgui/batchqueueentry.h b/rtgui/batchqueueentry.h index 384e12e80..caf1b8eff 100644 --- a/rtgui/batchqueueentry.h +++ b/rtgui/batchqueueentry.h @@ -53,6 +53,7 @@ public: int sequence; SaveFormat saveFormat; bool forceFormatOpts; + bool fast_pipeline; BatchQueueEntry (rtengine::ProcessingJob* job, const rtengine::procparams::ProcParams& pparams, Glib::ustring fname, int prevw, int prevh, Thumbnail* thm = nullptr); ~BatchQueueEntry (); diff --git a/rtgui/batchtoolpanelcoord.cc b/rtgui/batchtoolpanelcoord.cc index e85ee8523..a854db612 100644 --- a/rtgui/batchtoolpanelcoord.cc +++ b/rtgui/batchtoolpanelcoord.cc @@ -25,31 +25,14 @@ using namespace rtengine::procparams; -BatchToolPanelCoordinator::BatchToolPanelCoordinator (FilePanel* parent) : ToolPanelCoordinator(), somethingChanged(false), parent(parent) +BatchToolPanelCoordinator::BatchToolPanelCoordinator (FilePanel* parent) : ToolPanelCoordinator(true), somethingChanged(false), parent(parent) { blockedUpdate = false; - // remove exif panel and iptc panel - std::vector::iterator epi = std::find (toolPanels.begin(), toolPanels.end(), exifpanel); - - if (epi != toolPanels.end()) { - toolPanels.erase (epi); - } - - std::vector::iterator ipi = std::find (toolPanels.begin(), toolPanels.end(), iptcpanel); - - if (ipi != toolPanels.end()) { - toolPanels.erase (ipi); - } - if (toolBar) { toolBar->setBatchMode (); } - toolPanelNotebook->remove_page (*metadataPanel); - metadataPanel = nullptr; - toiM = nullptr; - for (size_t i = 0; i < toolPanels.size(); i++) { toolPanels[i]->setBatchMode (true); } @@ -157,15 +140,19 @@ void BatchToolPanelCoordinator::initSession () vignetting->setAdjusterBehavior (false, false, false, false); colorappearance->setAdjusterBehavior (false, false, false, false, false, false, false, false, false, false, false, false, false); rotate->setAdjusterBehavior (false); + resize->setAdjusterBehavior (false); distortion->setAdjusterBehavior (false); perspective->setAdjusterBehavior (false); gradient->setAdjusterBehavior (false, false, false, false); pcvignette->setAdjusterBehavior (false, false, false); cacorrection->setAdjusterBehavior (false); - sharpening->setAdjusterBehavior (false); + sharpening->setAdjusterBehavior (false, false, false, false, false, false); + prsharpening->setAdjusterBehavior (false, false, false, false, false, false); sharpenEdge->setAdjusterBehavior (false, false); sharpenMicro->setAdjusterBehavior (false, false); icm->setAdjusterBehavior (false, false); + epd->setAdjusterBehavior (false, false, false, false, false); + fattal->setAdjusterBehavior (false, false); chmixer->setAdjusterBehavior (false); blackwhite->setAdjusterBehavior (false, false); @@ -196,12 +183,17 @@ void BatchToolPanelCoordinator::initSession () vignetting->setAdjusterBehavior (options.baBehav[ADDSET_VIGN_AMOUNT], options.baBehav[ADDSET_VIGN_RADIUS], options.baBehav[ADDSET_VIGN_STRENGTH], options.baBehav[ADDSET_VIGN_CENTER]); colorappearance->setAdjusterBehavior (options.baBehav[ADDSET_CAT_DEGREE], options.baBehav[ADDSET_CAT_ADAPTSCENE], options.baBehav[ADDSET_CAT_ADAPTVIEWING], options.baBehav[ADDSET_CAT_BADPIX], options.baBehav[ADDSET_CAT_LIGHT], options.baBehav[ADDSET_CAT_CHROMA], options.baBehav[ADDSET_CAT_CONTRAST], options.baBehav[ADDSET_CAT_RSTPRO], options.baBehav[ADDSET_CAT_BRIGHT], options.baBehav[ADDSET_CAT_CONTRAST_Q], options.baBehav[ADDSET_CAT_CHROMA_S], options.baBehav[ADDSET_CAT_CHROMA_M], options.baBehav[ADDSET_CAT_HUE]); rotate->setAdjusterBehavior (options.baBehav[ADDSET_ROTATE_DEGREE]); + resize->setAdjusterBehavior (options.baBehav[ADDSET_RESIZE_SCALE]); distortion->setAdjusterBehavior (options.baBehav[ADDSET_DIST_AMOUNT]); perspective->setAdjusterBehavior (options.baBehav[ADDSET_PERSPECTIVE]); gradient->setAdjusterBehavior (options.baBehav[ADDSET_GRADIENT_DEGREE], options.baBehav[ADDSET_GRADIENT_FEATHER], options.baBehav[ADDSET_GRADIENT_STRENGTH], options.baBehav[ADDSET_GRADIENT_CENTER]); pcvignette->setAdjusterBehavior (options.baBehav[ADDSET_PCVIGNETTE_STRENGTH], options.baBehav[ADDSET_PCVIGNETTE_FEATHER], options.baBehav[ADDSET_PCVIGNETTE_ROUNDNESS]); cacorrection->setAdjusterBehavior (options.baBehav[ADDSET_CA]); - sharpening->setAdjusterBehavior (options.baBehav[ADDSET_SHARP_AMOUNT]); + sharpening->setAdjusterBehavior (options.baBehav[ADDSET_SHARP_RADIUS], options.baBehav[ADDSET_SHARP_AMOUNT], options.baBehav[ADDSET_SHARP_DAMPING], options.baBehav[ADDSET_SHARP_ITER], options.baBehav[ADDSET_SHARP_EDGETOL], options.baBehav[ADDSET_SHARP_HALOCTRL]); + prsharpening->setAdjusterBehavior (options.baBehav[ADDSET_SHARP_RADIUS], options.baBehav[ADDSET_SHARP_AMOUNT], options.baBehav[ADDSET_SHARP_DAMPING], options.baBehav[ADDSET_SHARP_ITER], options.baBehav[ADDSET_SHARP_EDGETOL], options.baBehav[ADDSET_SHARP_HALOCTRL]); + epd->setAdjusterBehavior (options.baBehav[ADDSET_EPD_STRENGTH], options.baBehav[ADDSET_EPD_GAMMA], options.baBehav[ADDSET_EPD_EDGESTOPPING], options.baBehav[ADDSET_EPD_SCALE], options.baBehav[ADDSET_EPD_REWEIGHTINGITERATES]); + fattal->setAdjusterBehavior (options.baBehav[ADDSET_FATTAL_ALPHA], options.baBehav[ADDSET_FATTAL_BETA]); + sharpenEdge->setAdjusterBehavior (options.baBehav[ADDSET_SHARPENEDGE_AMOUNT], options.baBehav[ADDSET_SHARPENEDGE_PASS]); sharpenMicro->setAdjusterBehavior (options.baBehav[ADDSET_SHARPENMICRO_AMOUNT], options.baBehav[ADDSET_SHARPENMICRO_UNIFORMITY]); icm->setAdjusterBehavior (options.baBehav[ADDSET_FREE_OUPUT_GAMMA], options.baBehav[ADDSET_FREE_OUTPUT_SLOPE]); @@ -223,450 +215,143 @@ void BatchToolPanelCoordinator::initSession () bayerrawexposure->setAdjusterBehavior (options.baBehav[ADDSET_RAWEXPOS_BLACKS]); xtransrawexposure->setAdjusterBehavior (options.baBehav[ADDSET_RAWEXPOS_BLACKS]); - if (options.baBehav[ADDSET_TC_EXPCOMP]) { - pparams.toneCurve.expcomp = 0; + // *INDENT-OFF* + if (options.baBehav[ADDSET_TC_EXPCOMP]) { pparams.toneCurve.expcomp = 0; } + if (options.baBehav[ADDSET_TC_HLCOMPAMOUNT]) { pparams.toneCurve.hlcompr = 0; } + if (options.baBehav[ADDSET_TC_HLCOMPTHRESH]) { pparams.toneCurve.hlcomprthresh = 0; } + if (options.baBehav[ADDSET_TC_BRIGHTNESS]) { pparams.toneCurve.brightness = 0; } + if (options.baBehav[ADDSET_TC_BLACKLEVEL]) {pparams.toneCurve.black = 0; } + if (options.baBehav[ADDSET_TC_SHCOMP]) { pparams.toneCurve.shcompr = 0; } + if (options.baBehav[ADDSET_TC_CONTRAST]) { pparams.toneCurve.contrast = 0; } + if (options.baBehav[ADDSET_TC_SATURATION]) { pparams.toneCurve.saturation = 0;} + if (options.baBehav[ADDSET_SH_HIGHLIGHTS]) { pparams.sh.highlights = 0; } + if (options.baBehav[ADDSET_SH_SHADOWS]) { pparams.sh.shadows = 0; } + if (options.baBehav[ADDSET_SH_LOCALCONTRAST]) { pparams.sh.localcontrast = 0; } + if (options.baBehav[ADDSET_LC_BRIGHTNESS]) { pparams.labCurve.brightness = 0; } + if (options.baBehav[ADDSET_LC_CONTRAST]) { pparams.labCurve.contrast = 0; } + if (options.baBehav[ADDSET_LC_CHROMATICITY]) { pparams.labCurve.chromaticity = 0; } + if (options.baBehav[ADDSET_SHARP_RADIUS]) { + pparams.sharpening.radius = pparams.sharpening.deconvradius = pparams.sharpening.edges_radius = 0; + pparams.prsharpening.radius = pparams.prsharpening.deconvradius = pparams.prsharpening.edges_radius = 0; } - - if (options.baBehav[ADDSET_TC_HLCOMPAMOUNT]) { - pparams.toneCurve.hlcompr = 0; - } - - if (options.baBehav[ADDSET_TC_HLCOMPTHRESH]) { - pparams.toneCurve.hlcomprthresh = 0; - } - - if (options.baBehav[ADDSET_TC_BRIGHTNESS]) { - pparams.toneCurve.brightness = 0; - } - - if (options.baBehav[ADDSET_TC_BLACKLEVEL]) { - pparams.toneCurve.black = 0; - } - - if (options.baBehav[ADDSET_TC_SHCOMP]) { - pparams.toneCurve.shcompr = 0; - } - - if (options.baBehav[ADDSET_TC_CONTRAST]) { - pparams.toneCurve.contrast = 0; - } - - if (options.baBehav[ADDSET_TC_SATURATION]) { - pparams.toneCurve.saturation = 0; - } - - if (options.baBehav[ADDSET_SH_HIGHLIGHTS]) { - pparams.sh.highlights = 0; - } - - if (options.baBehav[ADDSET_SH_SHADOWS]) { - pparams.sh.shadows = 0; - } - - if (options.baBehav[ADDSET_SH_LOCALCONTRAST]) { - pparams.sh.localcontrast = 0; - } - - if (options.baBehav[ADDSET_LC_BRIGHTNESS]) { - pparams.labCurve.brightness = 0; - } - - if (options.baBehav[ADDSET_LC_CONTRAST]) { - pparams.labCurve.contrast = 0; - } - - if (options.baBehav[ADDSET_LC_CHROMATICITY]) { - pparams.labCurve.chromaticity = 0; - } - if (options.baBehav[ADDSET_SHARP_AMOUNT]) { - pparams.sharpening.amount = 0; + pparams.sharpening.amount = pparams.sharpening.deconvamount = + pparams.prsharpening.amount = pparams.prsharpening.deconvamount = 0; } - - if (options.baBehav[ADDSET_SHARPENEDGE_AMOUNT]) { - pparams.sharpenEdge.amount = 0; + if (options.baBehav[ADDSET_SHARP_DAMPING]) { pparams.sharpening.deconvdamping = pparams.prsharpening.deconvdamping = 0; } + if (options.baBehav[ADDSET_SHARP_ITER]) { pparams.sharpening.deconviter = pparams.prsharpening.deconviter = 0; } + if (options.baBehav[ADDSET_SHARP_EDGETOL]) { pparams.sharpening.edges_tolerance = pparams.prsharpening.edges_tolerance = 0; } + if (options.baBehav[ADDSET_SHARP_HALOCTRL]) { pparams.sharpening.halocontrol_amount = pparams.prsharpening.halocontrol_amount = 0; } + if (options.baBehav[ADDSET_SHARPENEDGE_AMOUNT]) { pparams.sharpenEdge.amount = 0; } + if (options.baBehav[ADDSET_SHARPENMICRO_AMOUNT]) { pparams.sharpenMicro.amount = 0; } + if (options.baBehav[ADDSET_SHARPENEDGE_PASS]) { pparams.sharpenEdge.passes = 0; } + if (options.baBehav[ADDSET_SHARPENMICRO_UNIFORMITY]) { pparams.sharpenMicro.uniformity = 0; } + if (options.baBehav[ADDSET_CHMIXER]) for (int i = 0; i < 3; i++) { pparams.chmixer.red[i] = pparams.chmixer.green[i] = pparams.chmixer.blue[i] = 0; } + if (options.baBehav[ADDSET_BLACKWHITE_HUES]) { + pparams.blackwhite.mixerRed = pparams.blackwhite.mixerOrange = pparams.blackwhite.mixerYellow = + pparams.blackwhite.mixerGreen = pparams.blackwhite.mixerCyan = pparams.blackwhite.mixerBlue = + pparams.blackwhite.mixerMagenta = pparams.blackwhite.mixerPurple = 0; } - - if (options.baBehav[ADDSET_SHARPENMICRO_AMOUNT]) { - pparams.sharpenMicro.amount = 0; - } - - if (options.baBehav[ADDSET_SHARPENEDGE_PASS]) { - pparams.sharpenEdge.passes = 0; - } - - if (options.baBehav[ADDSET_SHARPENMICRO_UNIFORMITY]) { - pparams.sharpenMicro.uniformity = 0; - } - - if (options.baBehav[ADDSET_CHMIXER]) for (int i = 0; i < 3; i++) { - pparams.chmixer.red[i] = pparams.chmixer.green[i] = pparams.chmixer.blue[i] = 0; - } - - if (options.baBehav[ADDSET_BLACKWHITE_HUES]) pparams.blackwhite.mixerRed = pparams.blackwhite.mixerOrange = pparams.blackwhite.mixerYellow = - pparams.blackwhite.mixerGreen = pparams.blackwhite.mixerCyan = pparams.blackwhite.mixerBlue = - pparams.blackwhite.mixerMagenta = pparams.blackwhite.mixerPurple = 0; - - if (options.baBehav[ADDSET_BLACKWHITE_GAMMA]) { - pparams.blackwhite.gammaRed = pparams.blackwhite.gammaGreen = pparams.blackwhite.gammaBlue = 0; - } - + if (options.baBehav[ADDSET_BLACKWHITE_GAMMA]) { pparams.blackwhite.gammaRed = pparams.blackwhite.gammaGreen = pparams.blackwhite.gammaBlue = 0; } //if (options.baBehav[ADDSET_LD_EDGETOLERANCE]) pparams.lumaDenoise.edgetolerance = 0; - - if (options.baBehav[ADDSET_WB_TEMPERATURE]) { - pparams.wb.temperature = 0; - } - - if (options.baBehav[ADDSET_WB_GREEN]) { - pparams.wb.green = 0; - } - - if (options.baBehav[ADDSET_WB_EQUAL]) { - pparams.wb.equal = 0; - } - - if (options.baBehav[ADDSET_WB_TEMPBIAS]) { - pparams.wb.tempBias = 0; - } - - if (options.baBehav[ADDSET_VIBRANCE_PASTELS]) { - pparams.vibrance.pastels = 0; - } - - if (options.baBehav[ADDSET_VIBRANCE_SATURATED]) { - pparams.vibrance.saturated = 0; - } - - if (options.baBehav[ADDSET_CAT_DEGREE]) { - pparams.colorappearance.degree = 0; - } - - if (options.baBehav[ADDSET_CAT_ADAPTSCENE]) { - pparams.colorappearance.adapscen = 0; - } - - if (options.baBehav[ADDSET_CAT_ADAPTVIEWING]) { - pparams.colorappearance.adaplum = 0; - } - - if (options.baBehav[ADDSET_CAT_BADPIX]) { - pparams.colorappearance.badpixsl = 0; - } - - if (options.baBehav[ADDSET_CAT_LIGHT]) { - pparams.colorappearance.jlight = 0; - } - - if (options.baBehav[ADDSET_CAT_BRIGHT]) { - pparams.colorappearance.qbright = 0; - } - - if (options.baBehav[ADDSET_CAT_CHROMA]) { - pparams.colorappearance.chroma = 0; - } - - if (options.baBehav[ADDSET_CAT_CHROMA_S]) { - pparams.colorappearance.schroma = 0; - } - - if (options.baBehav[ADDSET_CAT_CHROMA_M]) { - pparams.colorappearance.mchroma = 0; - } - - if (options.baBehav[ADDSET_CAT_RSTPRO]) { - pparams.colorappearance.rstprotection = 0; - } - - if (options.baBehav[ADDSET_CAT_CONTRAST]) { - pparams.colorappearance.contrast = 0; - } - - if (options.baBehav[ADDSET_CAT_CONTRAST_Q]) { - pparams.colorappearance.qcontrast = 0; - } - - if (options.baBehav[ADDSET_CAT_HUE]) { - pparams.colorappearance.colorh = 0; - } - - if (options.baBehav[ADDSET_FREE_OUPUT_GAMMA]) { - pparams.icm.gampos = 0; - } - - if (options.baBehav[ADDSET_FREE_OUTPUT_SLOPE]) { - pparams.icm.slpos = 0; - } - + if (options.baBehav[ADDSET_WB_TEMPERATURE]) { pparams.wb.temperature = 0; } + if (options.baBehav[ADDSET_WB_GREEN]) { pparams.wb.green = 0; } + if (options.baBehav[ADDSET_WB_EQUAL]) { pparams.wb.equal = 0; } + if (options.baBehav[ADDSET_WB_TEMPBIAS]) { pparams.wb.tempBias = 0; } + if (options.baBehav[ADDSET_VIBRANCE_PASTELS]) { pparams.vibrance.pastels = 0; } + if (options.baBehav[ADDSET_VIBRANCE_SATURATED]) { pparams.vibrance.saturated = 0; } + if (options.baBehav[ADDSET_CAT_DEGREE]) { pparams.colorappearance.degree = 0; } + if (options.baBehav[ADDSET_CAT_ADAPTSCENE]) { pparams.colorappearance.adapscen = 0; } + if (options.baBehav[ADDSET_CAT_ADAPTVIEWING]) { pparams.colorappearance.adaplum = 0; } + if (options.baBehav[ADDSET_CAT_BADPIX]) { pparams.colorappearance.badpixsl = 0; } + if (options.baBehav[ADDSET_CAT_LIGHT]) { pparams.colorappearance.jlight = 0; } + if (options.baBehav[ADDSET_CAT_BRIGHT]) { pparams.colorappearance.qbright = 0; } + if (options.baBehav[ADDSET_CAT_CHROMA]) { pparams.colorappearance.chroma = 0; } + if (options.baBehav[ADDSET_CAT_CHROMA_S]) { pparams.colorappearance.schroma = 0; } + if (options.baBehav[ADDSET_CAT_CHROMA_M]) { pparams.colorappearance.mchroma = 0; } + if (options.baBehav[ADDSET_CAT_RSTPRO]) { pparams.colorappearance.rstprotection = 0; } + if (options.baBehav[ADDSET_CAT_CONTRAST]) { pparams.colorappearance.contrast = 0; } + if (options.baBehav[ADDSET_CAT_CONTRAST_Q]) { pparams.colorappearance.qcontrast = 0; } + if (options.baBehav[ADDSET_CAT_HUE]) { pparams.colorappearance.colorh = 0; } + if (options.baBehav[ADDSET_FREE_OUPUT_GAMMA]) { pparams.icm.gampos = 0; } + if (options.baBehav[ADDSET_FREE_OUTPUT_SLOPE]) { pparams.icm.slpos = 0; } //if (options.baBehav[ADDSET_CBOOST_AMOUNT]) pparams.colorBoost.amount = 0; - //if (options.baBehav[ADDSET_CS_BLUEYELLOW]) pparams.colorShift.a = 0; //if (options.baBehav[ADDSET_CS_GREENMAGENTA]) pparams.colorShift.b = 0; - if (options.baBehav[ADDSET_COLORTONING_SPLIT]) pparams.colorToning.redlow = pparams.colorToning.greenlow = pparams.colorToning.bluelow = - pparams.colorToning.redmed = pparams.colorToning.greenmed = pparams.colorToning.bluemed = - pparams.colorToning.redhigh = pparams.colorToning.greenhigh = pparams.colorToning.bluehigh = - pparams.colorToning.satlow = pparams.colorToning.sathigh = 0; - - if (options.baBehav[ADDSET_COLORTONING_SATTHRESHOLD]) { - pparams.colorToning.satProtectionThreshold = 0; + if (options.baBehav[ADDSET_COLORTONING_SPLIT]) { + pparams.colorToning.redlow = pparams.colorToning.greenlow = pparams.colorToning.bluelow = + pparams.colorToning.redmed = pparams.colorToning.greenmed = pparams.colorToning.bluemed = + pparams.colorToning.redhigh = pparams.colorToning.greenhigh = pparams.colorToning.bluehigh = + pparams.colorToning.satlow = pparams.colorToning.sathigh = 0; } - - if (options.baBehav[ADDSET_COLORTONING_SATOPACITY]) { - pparams.colorToning.saturatedOpacity = 0; - } - - if (options.baBehav[ADDSET_COLORTONING_BALANCE]) { - pparams.colorToning.balance = 0; - } - - if (options.baBehav[ADDSET_COLORTONING_STRENGTH]) { - pparams.colorToning.strength = 0; - } - - if (options.baBehav[ADDSET_FILMSIMULATION_STRENGTH]) { - pparams.filmSimulation.strength = 0; - } - - if (options.baBehav[ADDSET_ROTATE_DEGREE]) { - pparams.rotate.degree = 0; - } - - if (options.baBehav[ADDSET_DIST_AMOUNT]) { - pparams.distortion.amount = 0; - } - - if (options.baBehav[ADDSET_PERSPECTIVE]) { - pparams.perspective.horizontal = pparams.perspective.vertical = 0; - } - - if (options.baBehav[ADDSET_GRADIENT_DEGREE]) { - pparams.gradient.degree = 0; - } - - if (options.baBehav[ADDSET_GRADIENT_FEATHER]) { - pparams.gradient.feather = 0; - } - - if (options.baBehav[ADDSET_GRADIENT_STRENGTH]) { - pparams.gradient.strength = 0; - } - - if (options.baBehav[ADDSET_GRADIENT_CENTER]) { - pparams.gradient.centerX = 0; - } - - if (options.baBehav[ADDSET_GRADIENT_CENTER]) { - pparams.gradient.centerY = 0; - } - - if (options.baBehav[ADDSET_PCVIGNETTE_STRENGTH]) { - pparams.pcvignette.strength = 0; - } - - if (options.baBehav[ADDSET_PCVIGNETTE_FEATHER]) { - pparams.pcvignette.feather = 0; - } - - if (options.baBehav[ADDSET_PCVIGNETTE_ROUNDNESS]) { - pparams.pcvignette.roundness = 0; - } - - if (options.baBehav[ADDSET_CA]) { - pparams.cacorrection.red = 0; - } - - if (options.baBehav[ADDSET_CA]) { - pparams.cacorrection.blue = 0; - } - - if (options.baBehav[ADDSET_VIGN_AMOUNT]) { - pparams.vignetting.amount = 0; - } - - if (options.baBehav[ADDSET_VIGN_RADIUS]) { - pparams.vignetting.radius = 0; - } - - if (options.baBehav[ADDSET_VIGN_STRENGTH]) { - pparams.vignetting.strength = 0; - } - - if (options.baBehav[ADDSET_VIGN_CENTER]) { - pparams.vignetting.centerX = 0; - } - - if (options.baBehav[ADDSET_VIGN_CENTER]) { - pparams.vignetting.centerY = 0; - } - - if (options.baBehav[ADDSET_DIRPYREQ]) for (int i = 0; i < 6; i++) { - pparams.dirpyrequalizer.mult[i] = 0; - } - - if (options.baBehav[ADDSET_DIRPYREQ_THRESHOLD]) { - pparams.dirpyrequalizer.threshold = 0; - } - - if (options.baBehav[ADDSET_DIRPYREQ_SKINPROTECT]) { - pparams.dirpyrequalizer.skinprotect = 0; - } - - if (options.baBehav[ADDSET_WA]) for (int i = 0; i < 8; i++) { - pparams.wavelet.c[i] = 0; - } - - if (options.baBehav[ADDSET_WA_THRESHOLD]) { - pparams.wavelet.threshold = 0; - } - - if (options.baBehav[ADDSET_WA_THRESHOLD2]) { - pparams.wavelet.threshold2 = 0; - } - - if (options.baBehav[ADDSET_WA_SKINPROTECT]) { - pparams.wavelet.skinprotect = 0; - } - - if (options.baBehav[ADDSET_WA_CHRO]) { - pparams.wavelet.chro = 0; - } - - if (options.baBehav[ADDSET_WA_CHROMA]) { - pparams.wavelet.chroma = 0; - } - - if (options.baBehav[ADDSET_WA_CONTRAST]) { - pparams.wavelet.contrast = 0; - } - - if (options.baBehav[ADDSET_WA_THRES]) { - pparams.wavelet.thres = 0; - } - - if (options.baBehav[ADDSET_WA_RESCON]) { - pparams.wavelet.rescon = 0; - } - - 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_THRR]) { - pparams.wavelet.thr = 0; - } - - if (options.baBehav[ADDSET_WA_THRRH]) { - pparams.wavelet.thrH = 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; - } - - if (options.baBehav[ADDSET_WA_STRENGTH]) { - pparams.wavelet.strength = 0; - } - - if (options.baBehav[ADDSET_WA_EDGEDETECT]) { - pparams.wavelet.edgedetect = 0; - } - - if (options.baBehav[ADDSET_WA_GAMMA]) { - pparams.wavelet.gamma = 0; - } - - if (options.baBehav[ADDSET_RETI_STR]) { - pparams.retinex.str = 0; - } - - if (options.baBehav[ADDSET_RETI_NEIGH]) { - pparams.retinex.neigh = 0; - } - - if (options.baBehav[ADDSET_RETI_LIMD]) { - pparams.retinex.limd = 0; - } - - if (options.baBehav[ADDSET_RETI_OFFS]) { - pparams.retinex.offs = 0; - } - - if (options.baBehav[ADDSET_RETI_VART]) { - pparams.retinex.vart = 0; - } - - if (options.baBehav[ADDSET_RETI_GAM]) { - pparams.retinex.gam = 0; - } - - if (options.baBehav[ADDSET_RETI_SLO]) { - pparams.retinex.slope = 0; - } - - if (options.baBehav[ADDSET_DIRPYRDN_LUMA]) { - pparams.dirpyrDenoise.luma = 0; - } - - if (options.baBehav[ADDSET_DIRPYRDN_CHROMA]) { - pparams.dirpyrDenoise.chroma = 0; - } - - if (options.baBehav[ADDSET_DIRPYRDN_CHROMARED]) { - pparams.dirpyrDenoise.redchro = 0; - } - - if (options.baBehav[ADDSET_DIRPYRDN_CHROMABLUE]) { - pparams.dirpyrDenoise.bluechro = 0; - } - -// pparams.dirpyrDenoise.Ldetail = pparams.dirpyrDenoise.luma = pparams.dirpyrDenoise.chroma = 0; - if (options.baBehav[ADDSET_DIRPYRDN_GAMMA]) { - pparams.dirpyrDenoise.gamma = 0; - } - - if (options.baBehav[ADDSET_RAWCACORR]) { - pparams.raw.cablue = pparams.raw.cared = 0; - } - - if (options.baBehav[ADDSET_RAWEXPOS_LINEAR]) { - pparams.raw.expos = 0; - } - - if (options.baBehav[ADDSET_RAWEXPOS_PRESER]) { - pparams.raw.preser = 0; - } - + if (options.baBehav[ADDSET_COLORTONING_SATTHRESHOLD]) { pparams.colorToning.satProtectionThreshold = 0; } + if (options.baBehav[ADDSET_COLORTONING_SATOPACITY]) { pparams.colorToning.saturatedOpacity = 0; } + if (options.baBehav[ADDSET_COLORTONING_BALANCE]) { pparams.colorToning.balance = 0; } + if (options.baBehav[ADDSET_COLORTONING_STRENGTH]) { pparams.colorToning.strength = 0; } + if (options.baBehav[ADDSET_FILMSIMULATION_STRENGTH]) { pparams.filmSimulation.strength = 0; } + if (options.baBehav[ADDSET_ROTATE_DEGREE]) { pparams.rotate.degree = 0; } + if (options.baBehav[ADDSET_RESIZE_SCALE]) { pparams.resize.scale = 0; } + if (options.baBehav[ADDSET_DIST_AMOUNT]) { pparams.distortion.amount = 0; } + if (options.baBehav[ADDSET_PERSPECTIVE]) { pparams.perspective.horizontal = pparams.perspective.vertical = 0; } + if (options.baBehav[ADDSET_GRADIENT_DEGREE]) { pparams.gradient.degree = 0; } + if (options.baBehav[ADDSET_GRADIENT_FEATHER]) { pparams.gradient.feather = 0; } + if (options.baBehav[ADDSET_GRADIENT_STRENGTH]) { pparams.gradient.strength = 0; } + if (options.baBehav[ADDSET_GRADIENT_CENTER]) { pparams.gradient.centerX = pparams.gradient.centerY = 0; } + if (options.baBehav[ADDSET_PCVIGNETTE_STRENGTH]) { pparams.pcvignette.strength = 0; } + if (options.baBehav[ADDSET_PCVIGNETTE_FEATHER]) { pparams.pcvignette.feather = 0; } + if (options.baBehav[ADDSET_PCVIGNETTE_ROUNDNESS]) { pparams.pcvignette.roundness = 0; } + if (options.baBehav[ADDSET_CA]) { pparams.cacorrection.red = pparams.cacorrection.blue = 0; } + if (options.baBehav[ADDSET_VIGN_AMOUNT]) { pparams.vignetting.amount = 0; } + if (options.baBehav[ADDSET_VIGN_RADIUS]) { pparams.vignetting.radius = 0; } + if (options.baBehav[ADDSET_VIGN_STRENGTH]) { pparams.vignetting.strength = 0; } + if (options.baBehav[ADDSET_VIGN_CENTER]) { pparams.vignetting.centerX = pparams.vignetting.centerY = 0; } + if (options.baBehav[ADDSET_DIRPYREQ]) for (int i = 0; i < 6; i++) { pparams.dirpyrequalizer.mult[i] = 0; } + if (options.baBehav[ADDSET_DIRPYREQ_THRESHOLD]) { pparams.dirpyrequalizer.threshold = 0; } + if (options.baBehav[ADDSET_DIRPYREQ_SKINPROTECT]) { pparams.dirpyrequalizer.skinprotect = 0; } + if (options.baBehav[ADDSET_WA]) for (int i = 0; i < 8; i++) { pparams.wavelet.c[i] = 0; } + if (options.baBehav[ADDSET_WA_THRESHOLD]) { pparams.wavelet.threshold = 0; } + if (options.baBehav[ADDSET_WA_THRESHOLD2]) { pparams.wavelet.threshold2 = 0; } + if (options.baBehav[ADDSET_WA_SKINPROTECT]) { pparams.wavelet.skinprotect = 0; } + if (options.baBehav[ADDSET_WA_CHRO]) { pparams.wavelet.chro = 0; } + if (options.baBehav[ADDSET_WA_CHROMA]) { pparams.wavelet.chroma = 0; } + if (options.baBehav[ADDSET_WA_CONTRAST]) { pparams.wavelet.contrast = 0; } + if (options.baBehav[ADDSET_WA_THRES]) { pparams.wavelet.thres = 0; } + if (options.baBehav[ADDSET_WA_RESCON]) { pparams.wavelet.rescon = 0; } + 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_THRR]) { pparams.wavelet.thr = 0; } + if (options.baBehav[ADDSET_WA_THRRH]) { pparams.wavelet.thrH = 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; } + if (options.baBehav[ADDSET_WA_STRENGTH]) { pparams.wavelet.strength = 0; } + if (options.baBehav[ADDSET_WA_EDGEDETECT]) { pparams.wavelet.edgedetect = 0; } + if (options.baBehav[ADDSET_WA_GAMMA]) { pparams.wavelet.gamma = 0; } + if (options.baBehav[ADDSET_RETI_STR]) { pparams.retinex.str = 0; } + if (options.baBehav[ADDSET_RETI_NEIGH]) { pparams.retinex.neigh = 0; } + if (options.baBehav[ADDSET_RETI_LIMD]) { pparams.retinex.limd = 0; } + if (options.baBehav[ADDSET_RETI_OFFS]) { pparams.retinex.offs = 0; } + if (options.baBehav[ADDSET_RETI_VART]) { pparams.retinex.vart = 0; } + if (options.baBehav[ADDSET_RETI_GAM]) { pparams.retinex.gam = 0; } + if (options.baBehav[ADDSET_RETI_SLO]) { pparams.retinex.slope = 0; } + if (options.baBehav[ADDSET_DIRPYRDN_LUMA]) { pparams.dirpyrDenoise.luma = 0; } + if (options.baBehav[ADDSET_DIRPYRDN_CHROMA]) { pparams.dirpyrDenoise.chroma = 0; } + if (options.baBehav[ADDSET_DIRPYRDN_CHROMARED]) { pparams.dirpyrDenoise.redchro = 0; } + if (options.baBehav[ADDSET_DIRPYRDN_CHROMABLUE]) { pparams.dirpyrDenoise.bluechro = 0; } + //pparams.dirpyrDenoise.Ldetail = pparams.dirpyrDenoise.luma = pparams.dirpyrDenoise.chroma = 0; + if (options.baBehav[ADDSET_DIRPYRDN_GAMMA]) { pparams.dirpyrDenoise.gamma = 0; } + if (options.baBehav[ADDSET_RAWCACORR]) { pparams.raw.cablue = pparams.raw.cared = 0; } + if (options.baBehav[ADDSET_RAWEXPOS_LINEAR]) { pparams.raw.expos = 0; } + if (options.baBehav[ADDSET_RAWEXPOS_PRESER]) { pparams.raw.preser = 0; } if (options.baBehav[ADDSET_RAWEXPOS_BLACKS]) { - pparams.raw.bayersensor.black0 = pparams.raw.bayersensor.black1 = pparams.raw.bayersensor.black2 = pparams.raw.bayersensor.black3 = 0; + pparams.raw.bayersensor.black0 = pparams.raw.bayersensor.black1 = pparams.raw.bayersensor.black2 = pparams.raw.bayersensor.black3 = pparams.raw.xtranssensor.blackred = pparams.raw.xtranssensor.blackgreen = pparams.raw.xtranssensor.blackblue = 0; } - - if (options.baBehav[ADDSET_RAWFFCLIPCONTROL]) { - pparams.raw.ff_clipControl = 0; - } - - if (options.baBehav[ADDSET_PREPROCESS_GREENEQUIL]) { - pparams.raw.bayersensor.greenthresh = 0; - } - - if (options.baBehav[ADDSET_PREPROCESS_LINEDENOISE]) { - pparams.raw.bayersensor.linenoise = 0; - } + if (options.baBehav[ADDSET_RAWFFCLIPCONTROL]) { pparams.raw.ff_clipControl = 0; } + if (options.baBehav[ADDSET_PREPROCESS_GREENEQUIL]) { pparams.raw.bayersensor.greenthresh = 0; } + if (options.baBehav[ADDSET_PREPROCESS_LINEDENOISE]) { pparams.raw.bayersensor.linenoise = 0; } + // *INDENT-ON* } for (size_t i = 0; i < toolPanels.size(); i++) { diff --git a/rtgui/cacheimagedata.cc b/rtgui/cacheimagedata.cc index 34983d46a..dbb3b2946 100644 --- a/rtgui/cacheimagedata.cc +++ b/rtgui/cacheimagedata.cc @@ -24,8 +24,9 @@ CacheImageData::CacheImageData () : md5(""), supported(false), format(FT_Invalid), rankOld(-1), inTrashOld(false), recentlySaved(false), - timeValid(false), year(0), month(0), day(0), hour(0), min(0), sec(0), exifValid(false), - fnumber(0.0), shutter(0.0), focalLen(0.0), focalLen35mm(0.0), focusDist(0.f), iso(0), + timeValid(false), year(0), month(0), day(0), hour(0), min(0), sec(0), exifValid(false), frameCount(1), + fnumber(0.0), shutter(0.0), focalLen(0.0), focalLen35mm(0.0), focusDist(0.f), iso(0), isHDR (false), + isPixelShift (false), sensortype(rtengine::ST_NONE), sampleFormat(rtengine::IIOSF_UNKNOWN), redAWBMul(-1.0), greenAWBMul(-1.0), blueAWBMul(-1.0), rotate(0), thumbImgType(0) { } @@ -138,6 +139,14 @@ int CacheImageData::load (const Glib::ustring& fname) iso = keyFile.get_integer ("ExifInfo", "ISO"); } + if (keyFile.has_key ("ExifInfo", "IsHDR")) { + isHDR = keyFile.get_boolean ("ExifInfo", "IsHDR"); + } + + if (keyFile.has_key ("ExifInfo", "IsPixelShift")) { + isPixelShift = keyFile.get_boolean ("ExifInfo", "IsPixelShift"); + } + if (keyFile.has_key ("ExifInfo", "ExpComp")) { expcomp = keyFile.get_string ("ExifInfo", "ExpComp"); } @@ -160,12 +169,21 @@ int CacheImageData::load (const Glib::ustring& fname) if (keyFile.has_key ("FileInfo", "Filetype")) { filetype = keyFile.get_string ("FileInfo", "Filetype"); } + if (keyFile.has_key ("FileInfo", "FrameCount")) { + frameCount = static_cast(keyFile.get_integer ("FileInfo", "FrameCount")); + } + if (keyFile.has_key ("FileInfo", "SampleFormat")) { + sampleFormat = (rtengine::IIO_Sample_Format)keyFile.get_integer ("FileInfo", "SampleFormat"); + } } if (format == FT_Raw && keyFile.has_group ("ExtraRawInfo")) { if (keyFile.has_key ("ExtraRawInfo", "ThumbImageType")) { thumbImgType = keyFile.get_integer ("ExtraRawInfo", "ThumbImageType"); } + if (keyFile.has_key ("ExtraRawInfo", "SensorType")) { + sensortype = keyFile.get_integer ("ExtraRawInfo", "SensorType"); + } } else { rotate = 0; thumbImgType = 0; @@ -235,6 +253,8 @@ int CacheImageData::save (const Glib::ustring& fname) keyFile.set_double ("ExifInfo", "FocalLen35mm", focalLen35mm); keyFile.set_double ("ExifInfo", "FocusDist", focusDist); keyFile.set_integer ("ExifInfo", "ISO", iso); + keyFile.set_boolean ("ExifInfo", "IsHDR", isHDR); + keyFile.set_boolean ("ExifInfo", "IsPixelShift", isPixelShift); keyFile.set_string ("ExifInfo", "ExpComp", expcomp); } @@ -242,9 +262,12 @@ int CacheImageData::save (const Glib::ustring& fname) keyFile.set_string ("ExifInfo", "CameraMake", camMake); keyFile.set_string ("ExifInfo", "CameraModel", camModel); keyFile.set_string ("FileInfo", "Filetype", filetype); + keyFile.set_integer ("FileInfo", "FrameCount", frameCount); + keyFile.set_integer ("FileInfo", "SampleFormat", sampleFormat); if (format == FT_Raw) { keyFile.set_integer ("ExtraRawInfo", "ThumbImageType", thumbImgType); + keyFile.set_integer ("ExtraRawInfo", "SensorType", sensortype); } keyData = keyFile.to_data (); diff --git a/rtgui/cacheimagedata.h b/rtgui/cacheimagedata.h index f655bd88b..52675d77b 100644 --- a/rtgui/cacheimagedata.h +++ b/rtgui/cacheimagedata.h @@ -21,8 +21,10 @@ #include #include "options.h" +#include "../rtengine/rtengine.h" +#include "../rtengine/imageformat.h" -class CacheImageData +class CacheImageData: public rtengine::FramesMetaData { public: @@ -46,11 +48,16 @@ public: char sec; // exif info bool exifValid; + unsigned short frameCount; double fnumber; double shutter; double focalLen, focalLen35mm; float focusDist; unsigned iso; + bool isHDR; + bool isPixelShift; + int sensortype; + rtengine::IIO_Sample_Format sampleFormat; Glib::ustring lens; Glib::ustring camMake; Glib::ustring camModel; @@ -76,9 +83,33 @@ public: int load (const Glib::ustring& fname); int save (const Glib::ustring& fname); - Glib::ustring getCamera() const - { - return Glib::ustring(camMake + " " + camModel); - } + //------------------------------------------------------------------------- + // FramesMetaData interface + //------------------------------------------------------------------------- + + unsigned int getRootCount () const { return -1; } + unsigned int getFrameCount () const { return frameCount; } + bool hasExif (unsigned int frame = 0) const { return false; } + rtexif::TagDirectory* getRootExifData (unsigned int root = 0) const { return nullptr; } + rtexif::TagDirectory* getFrameExifData (unsigned int frame = 0) const { return nullptr; } + rtexif::TagDirectory* getBestExifData (rtengine::ImageSource *imgSource, rtengine::procparams::RAWParams *rawParams) const { return nullptr; } + bool hasIPTC (unsigned int frame = 0) const { return false; } + rtengine::procparams::IPTCPairs getIPTCData (unsigned int frame = 0) const { return rtengine::procparams::IPTCPairs(); } + tm getDateTime (unsigned int frame = 0) const { return tm{}; } + time_t getDateTimeAsTS(unsigned int frame = 0) const { return time_t(-1); } + int getISOSpeed (unsigned int frame = 0) const { return iso; } + double getFNumber (unsigned int frame = 0) const { return fnumber; } + double getFocalLen (unsigned int frame = 0) const { return focalLen; } + double getFocalLen35mm (unsigned int frame = 0) const { return focalLen35mm; } + float getFocusDist (unsigned int frame = 0) const { return focusDist; } + double getShutterSpeed (unsigned int frame = 0) const { return shutter; } + double getExpComp (unsigned int frame = 0) const { return atof(expcomp.c_str()); } + std::string getMake (unsigned int frame = 0) const { return camMake; } + std::string getModel (unsigned int frame = 0) const { return camModel; } + std::string getLens (unsigned int frame = 0) const { return lens; } + std::string getOrientation (unsigned int frame = 0) const { return ""; } // TODO + bool getPixelShift (unsigned int frame = 0) const { return isPixelShift; } + bool getHDR (unsigned int frame = 0) const { return isHDR; } + rtengine::IIOSampleFormat getSampleFormat (unsigned int frame = 0) const { return sampleFormat; } }; #endif diff --git a/rtgui/config.h.in b/rtgui/config.h.in index cab481278..fdf64b73c 100644 --- a/rtgui/config.h.in +++ b/rtgui/config.h.in @@ -25,5 +25,6 @@ #define DOC_SEARCH_PATH "${DOCDIR}" #define CREDITS_SEARCH_PATH "${CREDITSDIR}" #define LICENCE_SEARCH_PATH "${LICENCEDIR}" +#define LENSFUN_DB_PATH "${LENSFUNDBDIR}" #endif diff --git a/rtgui/crop.cc b/rtgui/crop.cc index 4b9e22fd2..546d910ba 100644 --- a/rtgui/crop.cc +++ b/rtgui/crop.cc @@ -54,7 +54,43 @@ int notifyListenerUI (void* data) } -Crop::Crop (): FoldableToolPanel(this, "crop", M("TP_CROP_LABEL"), false, true), opt(0), wDirty(true), hDirty(true), xDirty(true), yDirty(true), lastFixRatio(true) +Crop::Crop(): + FoldableToolPanel(this, "crop", M("TP_CROP_LABEL"), false, true), + crop_ratios{ + {"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... + }, + opt(0), + wDirty(true), + hDirty(true), + xDirty(true), + yDirty(true), + lastFixRatio(true) { clistener = nullptr; @@ -145,70 +181,9 @@ Crop::Crop (): FoldableToolPanel(this, "crop", M("TP_CROP_LABEL"), false, true), ppi->set_value (300); // ppibox END - /**************** - * Crop Ratio - *****************/ - int NumberOfCropRatios = 26; //!!! change this value when adding new crop ratios - cropratio.resize (NumberOfCropRatios); - - cropratio[0].label = "3:2"; - cropratio[0].value = 3.0 / 2.0; - cropratio[1].label = "4:3"; - cropratio[1].value = 4.0 / 3.0; - cropratio[2].label = "16:9"; - cropratio[2].value = 16.0 / 9.0; - cropratio[3].label = "16:10"; - cropratio[3].value = 16.0 / 10.0; - cropratio[4].label = "1:1"; - cropratio[4].value = 1.0 / 1.0; - cropratio[5].label = "2:1"; - cropratio[5].value = 2.0 / 1.0; - cropratio[6].label = "3:1"; - cropratio[6].value = 3.0 / 1.0; - cropratio[7].label = "4:1"; - cropratio[7].value = 4.0 / 1.0; - cropratio[8].label = "5:1"; - cropratio[8].value = 5.0 / 1.0; - cropratio[9].label = "6:1"; - cropratio[9].value = 6.0 / 1.0; - cropratio[10].label = "7:1"; - cropratio[10].value = 7.0 / 1.0; - cropratio[11].label = "4:5"; - cropratio[11].value = 4.0 / 5.0; - cropratio[12].label = "5:7"; - cropratio[12].value = 5.0 / 7.0; - cropratio[13].label = "6:7"; - cropratio[13].value = 6.0 / 7.0; - cropratio[14].label = "6:17"; - cropratio[14].value = 6.0 / 17.0; - cropratio[15].label = "24:65 - XPAN"; - cropratio[15].value = 24.0 / 65.0; - cropratio[16].label = "1.414 - DIN EN ISO 216"; - cropratio[16].value = 1.414; - cropratio[17].label = "3.5:5"; - cropratio[17].value = 3.5 / 5.0; - cropratio[18].label = "8.5:11 - US Letter"; - cropratio[18].value = 8.5 / 11.0; - cropratio[19].label = "9.5:12"; - cropratio[19].value = 9.5 / 12.0; - cropratio[20].label = "10:12"; - cropratio[20].value = 10.0 / 12.0; - cropratio[21].label = "11:14"; - cropratio[21].value = 11.0 / 14.0; - cropratio[22].label = "11:17 - Tabloid"; - cropratio[22].value = 11.0 / 17.0; - cropratio[23].label = "13:19"; - cropratio[23].value = 13.0 / 19.0; - cropratio[24].label = "17:22"; - cropratio[24].value = 17.0 / 22.0; - cropratio[25].label = "45:35 - ePassport"; - cropratio[25].value = 45.0 / 35.0; - - - - // populate the combobox - for (int i = 0; i < NumberOfCropRatios; i++) { - ratio->append (cropratio[i].label); + // Populate the combobox + for (const auto& crop_ratio : crop_ratios) { + ratio->append (crop_ratio.label); } ratio->set_active (0); @@ -320,7 +295,7 @@ void Crop::read (const ProcParams* pp, const ParamsEdited* pedited) ratio->set_active_text (pp->crop.ratio); fixr->set_active (pp->crop.fixratio); - const bool flip_orientation = pp->crop.fixratio && cropratio[ratio->get_active_row_number()].value < 1.0; + const bool flip_orientation = pp->crop.fixratio && crop_ratios[ratio->get_active_row_number()].value < 1.0; if (pp->crop.orientation == "Landscape") { orientation->set_active (flip_orientation ? 1 : 0); @@ -415,7 +390,7 @@ void Crop::write (ProcParams* pp, ParamsEdited* pedited) pp->crop.ratio = ratio->get_active_text (); // 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() && cropratio[ratio->get_active_row_number()].value < 1.0; + const bool flip_orientation = fixr->get_active() && crop_ratios[ratio->get_active_row_number()].value < 1.0; if (orientation->get_active_row_number() == 0) { pp->crop.orientation = flip_orientation ? "Portrait" : "Landscape"; @@ -1289,7 +1264,7 @@ double Crop::getRatio () return r; } - r = cropratio[ratio->get_active_row_number()].value; + r = crop_ratios[ratio->get_active_row_number()].value; if (r < 1.0) { r = 1.0 / r; // convert to long side first (eg 4:5 becomes 5:4) diff --git a/rtgui/crop.h b/rtgui/crop.h index 4c2d7a209..e786d8364 100644 --- a/rtgui/crop.h +++ b/rtgui/crop.h @@ -33,11 +33,6 @@ public: virtual void cropSelectRequested() = 0; }; -struct CropRatio { - Glib::ustring label; - double value; -}; - class Crop final : public ToolParamBlock, public CropGUIListener, @@ -94,6 +89,15 @@ public: void rotateCrop (int deg, bool hflip, bool vflip); private: + struct CropRatio { + Glib::ustring label; + double value; + }; + + const std::vector crop_ratios; + + void adjustCropToRatio(); + Gtk::CheckButton* fixr; MyComboBoxText* ratio; MyComboBoxText* orientation; @@ -116,8 +120,6 @@ private: int lastRotationDeg; sigc::connection xconn, yconn, wconn, hconn, fconn, rconn, oconn, gconn; bool wDirty, hDirty, xDirty, yDirty, lastFixRatio; - void adjustCropToRatio(); - std::vector cropratio; IdleRegister idle_register; }; diff --git a/rtgui/cropwindow.cc b/rtgui/cropwindow.cc index 8af0541fe..4e5e885ea 100644 --- a/rtgui/cropwindow.cc +++ b/rtgui/cropwindow.cc @@ -1324,6 +1324,8 @@ void CropWindow::expose (Cairo::RefPtr cr) cr->set_source_rgb (0, 0, 0); } else if (backColor == 2) { cr->set_source_rgb (1, 1, 1); + } else if (backColor == 3) { + cr->set_source_rgb (0.467, 0.467, 0.467); } cr->set_line_width (0.); @@ -1359,13 +1361,13 @@ void CropWindow::expose (Cairo::RefPtr cr) imgH = cropHandler.cropPixbuf->get_height (); exposeVersion++; - bool showcs = iarea->indClippedPanel->showClippedShadows(); - bool showch = iarea->indClippedPanel->showClippedHighlights(); const bool showR = iarea->previewModePanel->showR(); // will show clipping if R channel is clipped const bool showG = iarea->previewModePanel->showG(); // will show clipping if G channel is clipped const bool showB = iarea->previewModePanel->showB(); // will show clipping if B channel is clipped const bool showL = iarea->previewModePanel->showL(); // will show clipping if L value is clipped - const bool showFocusMask = iarea->previewModePanel->showFocusMask(); + const bool showFocusMask = iarea->indClippedPanel->showFocusMask(); + bool showcs = iarea->indClippedPanel->showClippedShadows(); + bool showch = iarea->indClippedPanel->showClippedHighlights(); // While the Right-side ALT is pressed, auto-enable highlight and shadow clipping indicators // TODO: Add linux/MacOS specific functions for alternative @@ -1621,7 +1623,7 @@ void CropWindow::expose (Cairo::RefPtr cr) const int shThreshold = options.shadowThreshold; const float ShawdowFac = 64.f / (options.shadowThreshold + 1); const float HighlightFac = 64.f / (256 - options.highlightThreshold); - const bool showclippedAny = (!showR && !showG && !showB && !showL); // will show clipping if any of RGB chanels is clipped + const bool showclippedAny = (!showR && !showG && !showB && !showL); // will show clipping if any (all) of RGB chanels is (shadow) clipped #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) @@ -1679,17 +1681,21 @@ void CropWindow::expose (Cairo::RefPtr cr) } if (showcs) { - if ((showclippedAny || showR) && currWS[0] <= shThreshold ) { + bool scR = currWS[0] <= shThreshold; + bool scG = currWS[1] <= shThreshold; + bool scB = currWS[2] <= shThreshold; + + if (((showclippedAny && (scG && scB)) || showR) && scR ) { delta += currWS[0]; changedSH = true; } - if ((showclippedAny || showG) && currWS[1] <= shThreshold ) { + if (((showclippedAny && (scR && scB)) || showG) && scG ) { delta += currWS[1]; changedSH = true; } - if ((showclippedAny || showB) && currWS[2] <= shThreshold ) { + if (((showclippedAny && (scR && scG)) || showB) && scB ) { delta += currWS[2]; changedSH = true; } diff --git a/rtgui/darkframe.cc b/rtgui/darkframe.cc index 83bad565a..ab9156d7d 100644 --- a/rtgui/darkframe.cc +++ b/rtgui/darkframe.cc @@ -46,7 +46,7 @@ DarkFrame::DarkFrame () : FoldableToolPanel(this, "darkframe", M("TP_DARKFRAME_L pack_start( *dfInfo, Gtk::PACK_SHRINK, 0); dfautoconn = dfAuto->signal_toggled().connect ( sigc::mem_fun(*this, &DarkFrame::dfAutoChanged), true); - dfFile = darkFrameFile->signal_file_set().connect ( sigc::mem_fun(*this, &DarkFrame::darkFrameChanged), true); + dfFile = darkFrameFile->signal_file_set().connect ( sigc::mem_fun(*this, &DarkFrame::darkFrameChanged)); //, true); btnReset->signal_clicked().connect( sigc::mem_fun(*this, &DarkFrame::darkFrameReset), true ); // Set filename filters diff --git a/rtgui/diagonalcurveeditorsubgroup.cc b/rtgui/diagonalcurveeditorsubgroup.cc index b64034b96..43a58b674 100644 --- a/rtgui/diagonalcurveeditorsubgroup.cc +++ b/rtgui/diagonalcurveeditorsubgroup.cc @@ -67,9 +67,9 @@ DiagonalCurveEditorSubGroup::DiagonalCurveEditorSubGroup (CurveEditorGroup* prt, } editPointCustom = Gtk::manage (new Gtk::ToggleButton ()); - initButton(*editPointCustom, Glib::ustring("gtk-edit.png"), Gtk::ALIGN_START, false, Glib::ustring(M("CURVEEDITOR_EDITPOINT_HINT"))); + initButton(*editPointCustom, Glib::ustring("gtk-edit.png"), Gtk::ALIGN_START, false, "CURVEEDITOR_EDITPOINT_HINT"); editCustom = Gtk::manage (new Gtk::ToggleButton()); - initButton(*editCustom, Glib::ustring("editmodehand.png"), Gtk::ALIGN_START, false, Glib::ustring(M("EDIT_PIPETTE_TOOLTIP"))); + initButton(*editCustom, Glib::ustring("editmodehand.png"), Gtk::ALIGN_START, false, "EDIT_PIPETTE_TOOLTIP"); editCustom->hide(); copyCustom = Gtk::manage (new Gtk::Button ()); initButton(*copyCustom, Glib::ustring("edit-copy.png"), Gtk::ALIGN_END, true); @@ -144,9 +144,9 @@ DiagonalCurveEditorSubGroup::DiagonalCurveEditorSubGroup (CurveEditorGroup* prt, } editPointNURBS = Gtk::manage (new Gtk::ToggleButton ()); - initButton(*editPointNURBS, Glib::ustring("gtk-edit.png"), Gtk::ALIGN_START, false, Glib::ustring(M("CURVEEDITOR_EDITPOINT_HINT"))); + initButton(*editPointNURBS, Glib::ustring("gtk-edit.png"), Gtk::ALIGN_START, false, "CURVEEDITOR_EDITPOINT_HINT"); editNURBS = Gtk::manage (new Gtk::ToggleButton()); - initButton(*editNURBS, Glib::ustring("editmodehand.png"), Gtk::ALIGN_START, false, Glib::ustring(M("EDIT_PIPETTE_TOOLTIP"))); + initButton(*editNURBS, Glib::ustring("editmodehand.png"), Gtk::ALIGN_START, false, "EDIT_PIPETTE_TOOLTIP"); editNURBS->hide(); copyNURBS = Gtk::manage (new Gtk::Button ()); initButton(*copyNURBS, Glib::ustring("edit-copy.png"), Gtk::ALIGN_END, true); @@ -224,7 +224,7 @@ DiagonalCurveEditorSubGroup::DiagonalCurveEditorSubGroup (CurveEditorGroup* prt, shcSelector->set_name("CurveSHCSelector"); // To handle the 4px gap between the SHCSelector and the curve through CSS editParam = Gtk::manage (new Gtk::ToggleButton()); - initButton(*editParam, Glib::ustring("editmodehand.png"), Gtk::ALIGN_START, false, Glib::ustring(M("EDIT_PIPETTE_TOOLTIP"))); + initButton(*editParam, Glib::ustring("editmodehand.png"), Gtk::ALIGN_START, false, "EDIT_PIPETTE_TOOLTIP"); editParam->hide(); copyParam = Gtk::manage (new Gtk::Button ()); initButton(*copyParam, Glib::ustring("edit-copy.png"), Gtk::ALIGN_END, true); diff --git a/rtgui/dynamicprofilepanel.cc b/rtgui/dynamicprofilepanel.cc index db3a19ed0..c8a8a1644 100644 --- a/rtgui/dynamicprofilepanel.cc +++ b/rtgui/dynamicprofilepanel.cc @@ -405,7 +405,7 @@ void DynamicProfilePanel::render_fnumber ( RENDER_RANGE_ (double, fnumber, [] (double f) { return std::string ("f/") + - rtengine::ImageMetaData::apertureToString (f); + rtengine::FramesMetaData::apertureToString (f); }); } @@ -421,7 +421,7 @@ void DynamicProfilePanel::render_shutterspeed ( Gtk::CellRenderer *cell, const Gtk::TreeModel::iterator &iter) { RENDER_RANGE_ (double, shutterspeed, - rtengine::ImageMetaData::shutterToString); + rtengine::FramesMetaData::shutterToString); } diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index 8d2d6251a..c2bec8692 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -72,61 +72,70 @@ int setprogressStrUI ( void *p ) } -bool find_default_monitor_profile(GdkWindow *rootwin, Glib::ustring &defprof, Glib::ustring &defprofname) +bool find_default_monitor_profile (GdkWindow *rootwin, Glib::ustring &defprof, Glib::ustring &defprofname) { #ifdef WIN32 - HDC hDC = GetDC(nullptr); + HDC hDC = GetDC (nullptr); if (hDC != nullptr) { - if (SetICMMode(hDC, ICM_ON)) { + if (SetICMMode (hDC, ICM_ON)) { char profileName[MAX_PATH + 1]; DWORD profileLength = MAX_PATH; - if (GetICMProfileA(hDC, &profileLength, profileName)) { - defprof = Glib::ustring(profileName); - defprofname = Glib::path_get_basename(defprof); - size_t pos = defprofname.rfind("."); + if (GetICMProfileA (hDC, &profileLength, profileName)) { + defprof = Glib::ustring (profileName); + defprofname = Glib::path_get_basename (defprof); + size_t pos = defprofname.rfind ("."); if (pos != Glib::ustring::npos) { - defprofname = defprofname.substr(0, pos); + defprofname = defprofname.substr (0, pos); } - defprof = Glib::ustring("file:") + defprof; + + defprof = Glib::ustring ("file:") + defprof; return true; } // might fail if e.g. the monitor has no profile } - ReleaseDC(NULL, hDC); + ReleaseDC (NULL, hDC); } + #elif !defined(__APPLE__) // taken from geeqie (image.c) and adapted // Originally licensed as GPL v2+, with the following copyright: // * Copyright (C) 2006 John Ellis // * Copyright (C) 2008 - 2016 The Geeqie Team - // + // guchar *prof = nullptr; gint proflen; GdkAtom type = GDK_NONE; gint format = 0; - if (gdk_property_get(rootwin, gdk_atom_intern("_ICC_PROFILE", FALSE), GDK_NONE, 0, 64 * 1024 * 1024, FALSE, &type, &format, &proflen, &prof) && proflen > 0) { - cmsHPROFILE p = cmsOpenProfileFromMem(prof, proflen); + + if (gdk_property_get (rootwin, gdk_atom_intern ("_ICC_PROFILE", FALSE), GDK_NONE, 0, 64 * 1024 * 1024, FALSE, &type, &format, &proflen, &prof) && proflen > 0) { + cmsHPROFILE p = cmsOpenProfileFromMem (prof, proflen); + if (p) { defprofname = "from GDK"; - defprof = Glib::build_filename(Options::rtdir, "GDK_ICC_PROFILE.icc"); - if (cmsSaveProfileToFile(p, defprof.c_str())) { - cmsCloseProfile(p); + defprof = Glib::build_filename (Options::rtdir, "GDK_ICC_PROFILE.icc"); + + if (cmsSaveProfileToFile (p, defprof.c_str())) { + cmsCloseProfile (p); + if (prof) { - g_free(prof); + g_free (prof); } - defprof = Glib::ustring("file:") + defprof; + + defprof = Glib::ustring ("file:") + defprof; return true; } } } + if (prof) { - g_free(prof); + g_free (prof); } + #endif return false; } @@ -153,26 +162,31 @@ private: #if !defined(__APPLE__) // monitor profile not supported on apple void prepareProfileBox () { - profileBox.setPreferredWidth(70, 200); + profileBox.setPreferredWidth (70, 200); setExpandAlignProperties (&profileBox, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL); profileBox.append (M ("PREFERENCES_PROFILE_NONE")); Glib::ustring defprofname; - if (find_default_monitor_profile(profileBox.get_root_window()->gobj(), defprof, defprofname)) { + + if (find_default_monitor_profile (profileBox.get_root_window()->gobj(), defprof, defprofname)) { profileBox.append (M ("MONITOR_PROFILE_SYSTEM") + " (" + defprofname + ")"); + if (options.rtSettings.autoMonitorProfile) { - rtengine::ICCStore::getInstance()->setDefaultMonitorProfileName(defprof); - profileBox.set_active(1); + rtengine::ICCStore::getInstance()->setDefaultMonitorProfileName (defprof); + profileBox.set_active (1); } else { - profileBox.set_active(0); + profileBox.set_active (0); } } else { profileBox.set_active (0); } + 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); } + profileBox.set_tooltip_text (profileBox.get_active_text ()); } #endif @@ -181,34 +195,34 @@ private: { // same order as the enum intentBox.addEntry ("intent-perceptual.png", M ("PREFERENCES_INTENT_PERCEPTUAL")); - intentBox.addEntry("intent-relative.png", M("PREFERENCES_INTENT_RELATIVE")); + intentBox.addEntry ("intent-relative.png", M ("PREFERENCES_INTENT_RELATIVE")); intentBox.addEntry ("intent-absolute.png", M ("PREFERENCES_INTENT_ABSOLUTE")); setExpandAlignProperties (intentBox.buttonGroup, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL); - intentBox.setSelected(1); + intentBox.setSelected (1); intentBox.show (); } void prepareSoftProofingBox () { Gtk::Image *softProofImage = Gtk::manage (new RTImage ("softProof.png")); - softProofImage->set_padding(0, 0); - softProof.add(*softProofImage); - softProof.set_relief(Gtk::RELIEF_NONE); - softProof.set_tooltip_markup(M("SOFTPROOF_TOOLTIP")); + softProofImage->set_padding (0, 0); + softProof.add (*softProofImage); + softProof.set_relief (Gtk::RELIEF_NONE); + softProof.set_tooltip_markup (M ("SOFTPROOF_TOOLTIP")); - softProof.set_active(false); - softProof.set_sensitive(canSProof); + softProof.set_active (false); + softProof.set_sensitive (canSProof); softProof.show (); Gtk::Image *spGamutCheckImage = Gtk::manage (new RTImage ("spGamutCheck.png")); - spGamutCheckImage->set_padding(0, 0); - spGamutCheck.add(*spGamutCheckImage); - spGamutCheck.set_relief(Gtk::RELIEF_NONE); - spGamutCheck.set_tooltip_markup(M("SOFTPROOF_GAMUTCHECK_TOOLTIP")); + spGamutCheckImage->set_padding (0, 0); + spGamutCheck.add (*spGamutCheckImage); + spGamutCheck.set_relief (Gtk::RELIEF_NONE); + spGamutCheck.set_tooltip_markup (M ("SOFTPROOF_GAMUTCHECK_TOOLTIP")); - spGamutCheck.set_active(false); - spGamutCheck.set_sensitive(false); + spGamutCheck.set_active (false); + spGamutCheck.set_sensitive (false); spGamutCheck.show (); } @@ -244,30 +258,35 @@ private: Glib::ustring profile; #if !defined(__APPLE__) // monitor profile not supported on apple + if (!defprof.empty() && profileBox.get_active_row_number () == 1) { profile = defprof; + if (profile.empty ()) { profile = options.rtSettings.monitorProfile; } + if (profile.empty ()) { profile = "sRGB IEC61966-2.1"; } } else if (profileBox.get_active_row_number () > 0) { profile = profileBox.get_active_text (); } + #else profile = "RT_sRGB"; #endif #if !defined(__APPLE__) // monitor profile not supported on apple + if (profileBox.get_active_row_number () == 0) { profile.clear (); intentBox.set_sensitive (false); intentBox.setSelected (1); - softProof.set_sensitive(false); - spGamutCheck.set_sensitive(false); + softProof.set_sensitive (false); + spGamutCheck.set_sensitive (false); profileBox.set_tooltip_text (""); @@ -279,38 +298,40 @@ private: if (supportsPerceptual || supportsRelativeColorimetric || supportsAbsoluteColorimetric) { intentBox.set_sensitive (true); - intentBox.setItemSensitivity(0, supportsPerceptual); - intentBox.setItemSensitivity(1, supportsRelativeColorimetric); - intentBox.setItemSensitivity(2, supportsAbsoluteColorimetric); - softProof.set_sensitive(canSProof); - spGamutCheck.set_sensitive(canSProof); + intentBox.setItemSensitivity (0, supportsPerceptual); + intentBox.setItemSensitivity (1, supportsRelativeColorimetric); + intentBox.setItemSensitivity (2, supportsAbsoluteColorimetric); + softProof.set_sensitive (canSProof); + spGamutCheck.set_sensitive (canSProof); } else { - intentBox.setItemSensitivity(0, true); - intentBox.setItemSensitivity(1, true); - intentBox.setItemSensitivity(2, true); + intentBox.setItemSensitivity (0, true); + intentBox.setItemSensitivity (1, true); + intentBox.setItemSensitivity (2, true); intentBox.set_sensitive (false); intentBox.setSelected (1); - softProof.set_sensitive(false); - spGamutCheck.set_sensitive(false); + softProof.set_sensitive (false); + spGamutCheck.set_sensitive (false); } profileBox.set_tooltip_text (profileBox.get_active_text ()); } + #endif rtengine::RenderingIntent intent; + switch (intentBox.getSelected ()) { - default: - case 0: - intent = rtengine::RI_PERCEPTUAL; - break; + default: + case 0: + intent = rtengine::RI_PERCEPTUAL; + break; - case 1: - intent = rtengine::RI_RELATIVE; - break; + case 1: + intent = rtengine::RI_RELATIVE; + break; - case 2: - intent = rtengine::RI_ABSOLUTE; - break; + case 2: + intent = rtengine::RI_ABSOLUTE; + break; } if (!processor) { @@ -320,8 +341,10 @@ private: if (!noEvent) { processor->beginUpdateParams (); } + processor->setMonitorProfile (profile, intent); processor->setSoftProofing (softProof.get_sensitive() && softProof.get_active(), spGamutCheck.get_sensitive() && spGamutCheck.get_active()); + if (!noEvent) { processor->endUpdateParams (rtengine::EvMonitorTransform); } @@ -331,36 +354,43 @@ private: { if (!canSProof) { ConnectionBlocker profileBlocker (softproofConn); - softProof.set_active(false); - softProof.set_sensitive(false); + softProof.set_active (false); + softProof.set_sensitive (false); #if !defined(__APPLE__) // monitor profile not supported on apple } else { - softProof.set_sensitive(profileBox.get_active_row_number () > 0); + softProof.set_sensitive (profileBox.get_active_row_number () > 0); #endif } - spGamutCheck.set_sensitive(softProof.get_sensitive() && softProof.get_active()); + + spGamutCheck.set_sensitive (softProof.get_sensitive() && softProof.get_active()); #if !defined(__APPLE__) // monitor profile not supported on apple + if (profileBox.get_active_row_number () > 0) { #endif + if (processor) { if (!noEvent) { processor->beginUpdateParams (); } + processor->setSoftProofing (softProof.get_sensitive() && softProof.get_active(), spGamutCheck.get_sensitive() && spGamutCheck.get_active()); + if (!noEvent) { processor->endUpdateParams (rtengine::EvMonitorTransform); } } + #if !defined(__APPLE__) // monitor profile not supported on apple } + #endif } public: explicit ColorManagementToolbar (rtengine::StagedImageProcessor* const& ipc) : intentBox (Glib::ustring (), true), - canSProof(!options.rtSettings.printerProfile.empty() && options.rtSettings.printerProfile != "None"), // assuming the printer profile exist! + canSProof (!options.rtSettings.printerProfile.empty() && options.rtSettings.printerProfile != "None"), // assuming the printer profile exist! processor (ipc) { #if !defined(__APPLE__) // monitor profile not supported on apple @@ -371,8 +401,8 @@ public: reset (); - softproofConn = softProof.signal_toggled().connect(sigc::mem_fun (this, &ColorManagementToolbar::softProofToggled)); - spGamutCheck.signal_toggled().connect(sigc::mem_fun (this, &ColorManagementToolbar::spGamutCheckToggled)); + softproofConn = softProof.signal_toggled().connect (sigc::mem_fun (this, &ColorManagementToolbar::softProofToggled)); + spGamutCheck.signal_toggled().connect (sigc::mem_fun (this, &ColorManagementToolbar::spGamutCheckToggled)); #if !defined(__APPLE__) // monitor profile not supported on apple profileConn = profileBox.signal_changed ().connect (sigc::mem_fun (this, &ColorManagementToolbar::profileBoxChanged)); #endif @@ -389,7 +419,7 @@ public: grid->attach_next_to (spGamutCheck, Gtk::POS_RIGHT, 1, 1); } - void canSoftProof(bool canSP) + void canSoftProof (bool canSP) { canSProof = canSP; updateSoftProofParameters(); @@ -398,7 +428,7 @@ public: void updateProcessor() { if (processor) { - updateParameters(true); + updateParameters (true); } } @@ -409,43 +439,44 @@ public: ConnectionBlocker profileBlocker (profileConn); if (!defprof.empty() && options.rtSettings.autoMonitorProfile) { - profileBox.set_active(1); + profileBox.set_active (1); } else { setActiveTextOrIndex (profileBox, options.rtSettings.monitorProfile, 0); } + #endif switch (options.rtSettings.monitorIntent) { - default: - case rtengine::RI_PERCEPTUAL: - intentBox.setSelected (0); - break; + default: + case rtengine::RI_PERCEPTUAL: + intentBox.setSelected (0); + break; - case rtengine::RI_RELATIVE: - intentBox.setSelected (1); - break; + case rtengine::RI_RELATIVE: + intentBox.setSelected (1); + break; - case rtengine::RI_ABSOLUTE: - intentBox.setSelected (2); - break; + case rtengine::RI_ABSOLUTE: + intentBox.setSelected (2); + break; } updateParameters (); } - void defaultMonitorProfileChanged(const Glib::ustring &profile_name, bool auto_monitor_profile) + void defaultMonitorProfileChanged (const Glib::ustring &profile_name, bool auto_monitor_profile) { ConnectionBlocker profileBlocker (profileConn); - + if (auto_monitor_profile && !defprof.empty()) { - rtengine::ICCStore::getInstance()->setDefaultMonitorProfileName(defprof); + rtengine::ICCStore::getInstance()->setDefaultMonitorProfileName (defprof); #ifndef __APPLE__ - profileBox.set_active(1); + profileBox.set_active (1); #endif } else { - rtengine::ICCStore::getInstance()->setDefaultMonitorProfileName(profile_name); + rtengine::ICCStore::getInstance()->setDefaultMonitorProfileName (profile_name); #ifndef __APPLE__ - setActiveTextOrIndex(profileBox, profile_name, 0); + setActiveTextOrIndex (profileBox, profile_name, 0); #endif } } @@ -453,7 +484,12 @@ public: }; EditorPanel::EditorPanel (FilePanel* filePanel) - : catalogPane(nullptr), realized(false), tbBeforeLock(nullptr), iHistoryShow(nullptr), iHistoryHide(nullptr), iTopPanel_1_Show(nullptr), iTopPanel_1_Hide(nullptr), iRightPanel_1_Show(nullptr), iRightPanel_1_Hide(nullptr), iBeforeLockON(nullptr), iBeforeLockOFF(nullptr), previewHandler(nullptr), beforePreviewHandler(nullptr), beforeIarea(nullptr), beforeBox(nullptr), afterBox(nullptr), beforeLabel(nullptr), afterLabel(nullptr), beforeHeaderBox(nullptr), afterHeaderBox(nullptr), parent(nullptr), parentWindow(nullptr), openThm(nullptr), isrc(nullptr), ipc(nullptr), beforeIpc(nullptr), err(0), isProcessing(false) + : catalogPane (nullptr), realized (false), tbBeforeLock (nullptr), iHistoryShow (nullptr), iHistoryHide (nullptr), + iTopPanel_1_Show (nullptr), iTopPanel_1_Hide (nullptr), iRightPanel_1_Show (nullptr), iRightPanel_1_Hide (nullptr), + iBeforeLockON (nullptr), iBeforeLockOFF (nullptr), previewHandler (nullptr), beforePreviewHandler (nullptr), + beforeIarea (nullptr), beforeBox (nullptr), afterBox (nullptr), beforeLabel (nullptr), afterLabel (nullptr), + beforeHeaderBox (nullptr), afterHeaderBox (nullptr), parent (nullptr), parentWindow (nullptr), openThm (nullptr), + selectedFrame(0), isrc (nullptr), ipc (nullptr), beforeIpc (nullptr), err (0), isProcessing (false) { epih = new EditorPanelIdleHelper; @@ -477,7 +513,7 @@ EditorPanel::EditorPanel (FilePanel* filePanel) profilep = Gtk::manage (new ProfilePanel ()); ppframe = new Gtk::Frame (); - ppframe->set_name("ProfilePanel"); + ppframe->set_name ("ProfilePanel"); ppframe->add (*profilep); ppframe->set_label (M ("PROFILEPANEL_LABEL")); //leftbox->pack_start (*ppframe, Gtk::PACK_SHRINK, 4); @@ -551,7 +587,7 @@ EditorPanel::EditorPanel (FilePanel* filePanel) iareapanel = new ImageAreaPanel (); tpc->setEditProvider (iareapanel->imageArea); - tpc->getToolBar()->setLockablePickerToolListener(iareapanel->imageArea); + tpc->getToolBar()->setLockablePickerToolListener (iareapanel->imageArea); Gtk::HBox* toolBarPanel = Gtk::manage (new Gtk::HBox ()); toolBarPanel->set_name ("EditorTopPanel"); @@ -580,7 +616,7 @@ EditorPanel::EditorPanel (FilePanel* filePanel) afterBox->pack_start (*iareapanel); beforeAfterBox = Gtk::manage (new Gtk::HBox()); - beforeAfterBox->set_name("BeforeAfterContainer"); + beforeAfterBox->set_name ("BeforeAfterContainer"); beforeAfterBox->pack_start (*afterBox); editbox->pack_start (*toolBarPanel, Gtk::PACK_SHRINK, 2); @@ -680,6 +716,7 @@ EditorPanel::EditorPanel (FilePanel* filePanel) iops->attach_next_to (*vsep2, Gtk::POS_LEFT, 1, 1); iops->attach_next_to (*progressLabel, Gtk::POS_LEFT, 1, 1); iops->attach_next_to (*vsep1, Gtk::POS_LEFT, 1, 1); + if (!gimpPlugin) { iops->attach_next_to (*sendtogimp, Gtk::POS_LEFT, 1, 1); } @@ -715,10 +752,10 @@ EditorPanel::EditorPanel (FilePanel* filePanel) editbox->show_all (); // build screen - hpanedl = Gtk::manage (new Gtk::Paned(Gtk::ORIENTATION_HORIZONTAL)); - hpanedl->set_name("EditorLeftPaned"); - hpanedr = Gtk::manage (new Gtk::Paned(Gtk::ORIENTATION_HORIZONTAL)); - hpanedr->set_name("EditorRightPaned"); + hpanedl = Gtk::manage (new Gtk::Paned (Gtk::ORIENTATION_HORIZONTAL)); + hpanedl->set_name ("EditorLeftPaned"); + hpanedr = Gtk::manage (new Gtk::Paned (Gtk::ORIENTATION_HORIZONTAL)); + hpanedr->set_name ("EditorRightPaned"); leftbox->reference (); vboxright->reference (); @@ -919,6 +956,14 @@ void EditorPanel::writeOptions() } } + +void EditorPanel::writeToolExpandedStatus (std::vector &tpOpen) +{ + if (tpc) { + tpc->writeToolExpandedStatus (tpOpen); + } +} + void EditorPanel::showTopPanel (bool show) { if (tbTopPanel_1->get_active() != show) { @@ -1026,7 +1071,7 @@ void EditorPanel::close () tpc->closeImage (); // this call stops image processing tpc->writeOptions (); rtengine::ImageSource* is = isrc->getImageSource(); - is->setProgressListener( nullptr ); + is->setProgressListener ( nullptr ); if (ipc) { ipc->setPreviewImageListener (nullptr); @@ -1039,7 +1084,7 @@ void EditorPanel::close () delete previewHandler; previewHandler = nullptr; - if(iareapanel) { + if (iareapanel) { iareapanel->imageArea->setPreviewHandler (nullptr); iareapanel->imageArea->setImProcCoordinator (nullptr); iareapanel->imageArea->unsubscribe(); @@ -1050,7 +1095,7 @@ void EditorPanel::close () navigator->previewWindow->setPreviewHandler (nullptr); // If the file was deleted somewhere, the openThm.descreaseRef delete the object, but we don't know here - if (Glib::file_test(fname, Glib::FILE_TEST_EXISTS)) { + if (Glib::file_test (fname, Glib::FILE_TEST_EXISTS)) { openThm->removeThumbnailListener (this); openThm->decreaseRef (); } @@ -1064,7 +1109,7 @@ void EditorPanel::saveProfile () } // If the file was deleted, do not generate ghost entries - if (Glib::file_test(fname, Glib::FILE_TEST_EXISTS)) { + if (Glib::file_test (fname, Glib::FILE_TEST_EXISTS)) { ProcParams params; ipc->getParams (¶ms); @@ -1097,6 +1142,18 @@ void EditorPanel::procParamsChanged (rtengine::procparams::ProcParams* params, r // if (ev!=EvPhotoLoaded) // saveLabel->set_markup (Glib::ustring("") + M("MAIN_BUTTON_SAVE") + ""); + + rtengine::eSensorType sensorType = isrc->getImageSource()->getSensorType(); + + selectedFrame = 0; + if (sensorType == rtengine::ST_BAYER) { + selectedFrame = params->raw.bayersensor.imageNum; + //} else if (sensorType == rtengine::ST_FUJI_XTRANS) { + // selectedFrame = params->raw.xtranssensor.imageNum; + } + selectedFrame = rtengine::LIM(selectedFrame, 0, isrc->getImageSource()->getMetaData()->getFrameCount() - 1); + + info_toggled(); } void EditorPanel::setProgressState (bool inProcessing) @@ -1112,10 +1169,11 @@ void EditorPanel::setProgressState (bool inProcessing) p->inProcessing = inProcessing; p->epih = epih; - const auto func = [](gpointer data) -> gboolean { - spsparams* const p = static_cast(data); + const auto func = [] (gpointer data) -> gboolean { + spsparams* const p = static_cast (data); - if (p->epih->destroyed) { + if (p->epih->destroyed) + { if (p->epih->pending == 1) { delete p->epih; } else { @@ -1134,7 +1192,7 @@ void EditorPanel::setProgressState (bool inProcessing) return FALSE; }; - idle_register.add(func, p); + idle_register.add (func, p); } void EditorPanel::setProgress (double p) @@ -1142,7 +1200,7 @@ void EditorPanel::setProgress (double p) spparams *s = new spparams; s->val = p; s->pProgress = progressLabel; - idle_register.add(setprogressStrUI, s); + idle_register.add (setprogressStrUI, s); } void EditorPanel::setProgressStr (Glib::ustring str) @@ -1151,7 +1209,7 @@ void EditorPanel::setProgressStr (Glib::ustring str) s->str = str; s->val = -1; s->pProgress = progressLabel; - idle_register.add(setprogressStrUI, s); + idle_register.add (setprogressStrUI, s); } // This is only called from the ThreadUI, so within the gtk thread @@ -1162,7 +1220,7 @@ void EditorPanel::refreshProcessingState (bool inProcessingP) if (inProcessingP) { if (processingStartedTime == 0) { - processingStartedTime = ::time(nullptr); + processingStartedTime = ::time (nullptr); } s->str = "PROGRESSBAR_PROCESSING"; @@ -1177,7 +1235,7 @@ void EditorPanel::refreshProcessingState (bool inProcessingP) // Ring a sound if it was a long event if (processingStartedTime != 0) { - time_t curTime = ::time(nullptr); + time_t curTime = ::time (nullptr); if (::difftime (curTime, processingStartedTime) > options.sndLngEditProcDoneSecs) { SoundManager::playSoundAsync (options.sndLngEditProcDone); @@ -1235,10 +1293,11 @@ void EditorPanel::error (Glib::ustring title, Glib::ustring descr) p->title = title; p->epih = epih; - const auto func = [](gpointer data) -> gboolean { + const auto func = [] (gpointer data) -> gboolean { errparams* const p = static_cast (data); - if (p->epih->destroyed) { + if (p->epih->destroyed) + { if (p->epih->pending == 1) { delete p->epih; } else { @@ -1257,54 +1316,66 @@ void EditorPanel::error (Glib::ustring title, Glib::ustring descr) return FALSE; }; - idle_register.add(func, p); + idle_register.add (func, p); } void EditorPanel::info_toggled () { Glib::ustring infoString; - Glib::ustring infoString1; //1-st line - Glib::ustring infoString2; //2-nd line - Glib::ustring infoString3; //3-rd line - Glib::ustring infoString4; //4-th line Glib::ustring expcomp; if (!ipc || !openThm) { return; } - const rtengine::ImageMetaData* idata = ipc->getInitialImage()->getMetaData(); + const rtengine::FramesMetaData* idata = ipc->getInitialImage()->getMetaData(); - if (idata && idata->hasExif()) { - infoString1 = Glib::ustring::compose ("%1 + %2", + if (idata && idata->hasExif(selectedFrame)) { + infoString = Glib::ustring::compose ("%1 + %2\nf/%3 %4s %5%6 %7mm", Glib::ustring (idata->getMake() + " " + idata->getModel()), - Glib::ustring (idata->getLens())); + Glib::ustring (idata->getLens()), + Glib::ustring (idata->apertureToString (idata->getFNumber(selectedFrame))), + Glib::ustring (idata->shutterToString (idata->getShutterSpeed(selectedFrame))), + M ("QINFO_ISO"), idata->getISOSpeed(selectedFrame), + Glib::ustring::format (std::setw (3), std::fixed, std::setprecision (2), idata->getFocalLen(selectedFrame))); - infoString2 = Glib::ustring::compose ("f/%1 %2s %3%4 %5mm", - Glib::ustring (idata->apertureToString (idata->getFNumber())), - Glib::ustring (idata->shutterToString (idata->getShutterSpeed())), - M ("QINFO_ISO"), idata->getISOSpeed(), - Glib::ustring::format (std::setw (3), std::fixed, std::setprecision (2), idata->getFocalLen())); + expcomp = Glib::ustring (idata->expcompToString (idata->getExpComp(selectedFrame), true)); // maskZeroexpcomp - expcomp = Glib::ustring (idata->expcompToString (idata->getExpComp(), true)); // maskZeroexpcomp - - if (expcomp != "") { - infoString2 = Glib::ustring::compose ("%1 %2EV", - infoString2, + if (!expcomp.empty ()) { + infoString = Glib::ustring::compose ("%1 %2EV", + infoString, expcomp /*Glib::ustring(idata->expcompToString(idata->getExpComp()))*/); } - infoString3 = Glib::ustring::compose ("%1%2", + infoString = Glib::ustring::compose ("%1\n%2%3", + infoString, escapeHtmlChars (Glib::path_get_dirname (openThm->getFileName())) + G_DIR_SEPARATOR_S, escapeHtmlChars (Glib::path_get_basename (openThm->getFileName())) ); int ww = ipc->getFullWidth(); int hh = ipc->getFullHeight(); //megapixels - infoString4 = Glib::ustring::compose ("%1 MP (%2x%3)", Glib::ustring::format (std::setw (4), std::fixed, std::setprecision (1), (float)ww * hh / 1000000), ww, hh); + infoString = Glib::ustring::compose ("%1\n%2 MP (%3x%4)", + infoString, + Glib::ustring::format (std::setw (4), std::fixed, std::setprecision (1), (float)ww * hh / 1000000), + ww, hh); - infoString = Glib::ustring::compose ("%1\n%2\n%3\n%4", infoString1, infoString2, infoString3, infoString4); + //adding special characteristics + bool isHDR = idata->getHDR(); + bool isPixelShift = idata->getPixelShift(); + unsigned int numFrames = idata->getFrameCount(); + if (isHDR) { + infoString = Glib::ustring::compose ("%1\n" + M("QINFO_HDR"), infoString, numFrames); + if (numFrames == 1) { + int sampleFormat = idata->getSampleFormat(selectedFrame); + infoString = Glib::ustring::compose ("%1 / %2", infoString, M(Glib::ustring::compose("SAMPLEFORMAT_%1", sampleFormat))); + } + } else if (isPixelShift) { + infoString = Glib::ustring::compose ("%1\n" + M("QINFO_PIXELSHIFT"), infoString, numFrames); + } else if (numFrames > 1) { + infoString = Glib::ustring::compose ("%1\n" + M("QINFO_FRAMECOUNT"), infoString, numFrames); + } } else { infoString = M ("QINFO_NOEXIF"); } @@ -1410,56 +1481,56 @@ bool EditorPanel::handleShortcutKey (GdkEventKey* event) // Editor Layout switch (event->keyval) { - case GDK_KEY_L: - if (tbTopPanel_1) { - tbTopPanel_1->set_active (!tbTopPanel_1->get_active()); // toggle top panel - } + case GDK_KEY_L: + if (tbTopPanel_1) { + tbTopPanel_1->set_active (!tbTopPanel_1->get_active()); // toggle top panel + } - if (ctrl) { - hidehp->set_active (!hidehp->get_active()); // toggle History (left panel) - } + if (ctrl) { + hidehp->set_active (!hidehp->get_active()); // toggle History (left panel) + } - if (alt) { - tbRightPanel_1->set_active (!tbRightPanel_1->get_active()); // toggle right panel - } + if (alt) { + tbRightPanel_1->set_active (!tbRightPanel_1->get_active()); // toggle right panel + } - return true; - break; - - case GDK_KEY_l: - if (!shift && !alt /*&& !ctrl*/) { - hidehp->set_active (!hidehp->get_active()); // toggle History (left panel) return true; - } + break; - if (alt && !ctrl) { // toggle right panel - tbRightPanel_1->set_active (!tbRightPanel_1->get_active()); - return true; - } + case GDK_KEY_l: + if (!shift && !alt /*&& !ctrl*/) { + hidehp->set_active (!hidehp->get_active()); // toggle History (left panel) + return true; + } - if (alt && ctrl) { // toggle left and right panels - hidehp->set_active (!hidehp->get_active()); - tbRightPanel_1->set_active (!tbRightPanel_1->get_active()); - return true; - } + if (alt && !ctrl) { // toggle right panel + tbRightPanel_1->set_active (!tbRightPanel_1->get_active()); + return true; + } - break; + if (alt && ctrl) { // toggle left and right panels + hidehp->set_active (!hidehp->get_active()); + tbRightPanel_1->set_active (!tbRightPanel_1->get_active()); + return true; + } - case GDK_KEY_m: // Maximize preview panel: hide top AND right AND history panels - if (!ctrl && !alt) { - toggleSidePanels(); - return true; - } + break; - break; + case GDK_KEY_m: // Maximize preview panel: hide top AND right AND history panels + if (!ctrl && !alt) { + toggleSidePanels(); + return true; + } - case GDK_KEY_M: // Maximize preview panel: hide top AND right AND history panels AND (fit image preview) - if (!ctrl && !alt) { - toggleSidePanelsZoomFit(); - return true; - } + break; - break; + case GDK_KEY_M: // Maximize preview panel: hide top AND right AND history panels AND (fit image preview) + if (!ctrl && !alt) { + toggleSidePanelsZoomFit(); + return true; + } + + break; } #ifdef __WIN32__ @@ -1482,170 +1553,172 @@ bool EditorPanel::handleShortcutKey (GdkEventKey* event) if (!ctrl) { // Normal switch (event->keyval) { - case GDK_KEY_bracketright: - tpc->coarse->rotateRight(); - return true; - - case GDK_KEY_bracketleft: - tpc->coarse->rotateLeft(); - return true; - - case GDK_KEY_i: - case GDK_KEY_I: - info->set_active (!info->get_active()); - return true; - - case GDK_KEY_B: - beforeAfter->set_active (!beforeAfter->get_active()); - return true; - - case GDK_KEY_plus: - case GDK_KEY_equal: - case GDK_KEY_KP_Add: - iareapanel->imageArea->zoomPanel->zoomInClicked(); - return true; - - case GDK_KEY_minus: - case GDK_KEY_underscore: - case GDK_KEY_KP_Subtract: - iareapanel->imageArea->zoomPanel->zoomOutClicked(); - return true; - - case GDK_KEY_z://GDK_1 - iareapanel->imageArea->zoomPanel->zoom11Clicked(); - return true; - - /* - #ifndef __WIN32__ - case GDK_KEY_9: // toggle background color of the preview - iareapanel->imageArea->previewModePanel->togglebackColor(); - return true; - #endif - */ - case GDK_KEY_r: //preview mode Red - iareapanel->imageArea->previewModePanel->toggleR(); - return true; - - case GDK_KEY_g: //preview mode Green - iareapanel->imageArea->previewModePanel->toggleG(); - return true; - - case GDK_KEY_b: //preview mode Blue - iareapanel->imageArea->previewModePanel->toggleB(); - return true; - - case GDK_KEY_v: //preview mode Luminosity - iareapanel->imageArea->previewModePanel->toggleL(); - return true; - - case GDK_KEY_F: //preview mode Focus Mask - iareapanel->imageArea->previewModePanel->toggleFocusMask(); - return true; - - case GDK_KEY_f: - iareapanel->imageArea->zoomPanel->zoomFitClicked(); - return true; - - case GDK_KEY_less: - iareapanel->imageArea->indClippedPanel->toggleClipped (false); - return true; - - case GDK_KEY_greater: - iareapanel->imageArea->indClippedPanel->toggleClipped (true); - return true; - - case GDK_KEY_F5: - openThm->openDefaultViewer ((event->state & GDK_SHIFT_MASK) ? 2 : 1); - return true; - - case GDK_KEY_y: // synchronize filebrowser with image in Editor - if (!simpleEditor && fPanel && !fname.empty()) { - fPanel->fileCatalog->selectImage (fname, false); + case GDK_KEY_bracketright: + tpc->coarse->rotateRight(); return true; - } - break; // to avoid gcc complain - - case GDK_KEY_x: // clear filters and synchronize filebrowser with image in Editor - if (!simpleEditor && fPanel && !fname.empty()) { - fPanel->fileCatalog->selectImage (fname, true); + case GDK_KEY_bracketleft: + tpc->coarse->rotateLeft(); return true; - } - break; // to avoid gcc complain + case GDK_KEY_i: + case GDK_KEY_I: + info->set_active (!info->get_active()); + return true; + + case GDK_KEY_B: + beforeAfter->set_active (!beforeAfter->get_active()); + return true; + + case GDK_KEY_plus: + case GDK_KEY_equal: + case GDK_KEY_KP_Add: + iareapanel->imageArea->zoomPanel->zoomInClicked(); + return true; + + case GDK_KEY_minus: + case GDK_KEY_underscore: + case GDK_KEY_KP_Subtract: + iareapanel->imageArea->zoomPanel->zoomOutClicked(); + return true; + + case GDK_KEY_z://GDK_1 + iareapanel->imageArea->zoomPanel->zoom11Clicked(); + return true; + + /* + #ifndef __WIN32__ + case GDK_KEY_9: // toggle background color of the preview + iareapanel->imageArea->previewModePanel->togglebackColor(); + return true; + #endif + */ + case GDK_KEY_r: //preview mode Red + iareapanel->imageArea->previewModePanel->toggleR(); + return true; + + case GDK_KEY_g: //preview mode Green + iareapanel->imageArea->previewModePanel->toggleG(); + return true; + + case GDK_KEY_b: //preview mode Blue + iareapanel->imageArea->previewModePanel->toggleB(); + return true; + + case GDK_KEY_v: //preview mode Luminosity + iareapanel->imageArea->previewModePanel->toggleL(); + return true; + + case GDK_KEY_F: //preview mode Focus Mask + iareapanel->imageArea->indClippedPanel->toggleFocusMask(); + return true; + + case GDK_KEY_less: + iareapanel->imageArea->indClippedPanel->toggleClipped (false); + return true; + + case GDK_KEY_greater: + iareapanel->imageArea->indClippedPanel->toggleClipped (true); + return true; + + case GDK_KEY_f: + iareapanel->imageArea->zoomPanel->zoomFitClicked(); + return true; + + case GDK_KEY_F5: + openThm->openDefaultViewer ((event->state & GDK_SHIFT_MASK) ? 2 : 1); + return true; + + case GDK_KEY_y: // synchronize filebrowser with image in Editor + if (!simpleEditor && fPanel && !fname.empty()) { + fPanel->fileCatalog->selectImage (fname, false); + return true; + } + + break; // to avoid gcc complain + + case GDK_KEY_x: // clear filters and synchronize filebrowser with image in Editor + if (!simpleEditor && fPanel && !fname.empty()) { + fPanel->fileCatalog->selectImage (fname, true); + return true; + } + + break; // to avoid gcc complain } } else { // With control switch (event->keyval) { - case GDK_KEY_S: - saveProfile(); - setProgressStr (M ("PROGRESSBAR_PROCESSING_PROFILESAVED")); - return true; + case GDK_KEY_S: + saveProfile(); + setProgressStr (M ("PROGRESSBAR_PROCESSING_PROFILESAVED")); + return true; - case GDK_KEY_s: - if (!gimpPlugin) { - saveAsPressed(); - } - return true; + case GDK_KEY_s: + if (!gimpPlugin) { + saveAsPressed(); + } - case GDK_KEY_b: - if (!gimpPlugin && !simpleEditor) { - queueImgPressed(); - } + return true; - return true; + case GDK_KEY_b: + if (!gimpPlugin && !simpleEditor) { + queueImgPressed(); + } - case GDK_KEY_e: - if (!gimpPlugin) { - sendToGimpPressed(); - } - return true; + return true; - case GDK_KEY_z: - history->undo (); - return true; + case GDK_KEY_e: + if (!gimpPlugin) { + sendToGimpPressed(); + } - case GDK_KEY_Z: - history->redo (); - return true; + return true; - case GDK_KEY_F5: - openThm->openDefaultViewer (3); - return true; + case GDK_KEY_z: + history->undo (); + return true; + + case GDK_KEY_Z: + history->redo (); + return true; + + case GDK_KEY_F5: + openThm->openDefaultViewer (3); + return true; } } //if (!ctrl) } //if (!alt) if (alt) { switch (event->keyval) { - case GDK_KEY_s: - history->addBookmarkPressed (); - setProgressStr (M ("PROGRESSBAR_SNAPSHOT_ADDED")); - return true; + case GDK_KEY_s: + history->addBookmarkPressed (); + setProgressStr (M ("PROGRESSBAR_SNAPSHOT_ADDED")); + return true; - case GDK_KEY_f: - iareapanel->imageArea->zoomPanel->zoomFitCropClicked(); - return true; + case GDK_KEY_f: + iareapanel->imageArea->zoomPanel->zoomFitCropClicked(); + return true; } } if (shift) { switch (event->keyval) { - case GDK_KEY_F3: // open Previous image from Editor's perspective - if (!simpleEditor && fPanel && !fname.empty()) { - EditorPanel::openPreviousEditorImage(); - return true; - } + case GDK_KEY_F3: // open Previous image from Editor's perspective + if (!simpleEditor && fPanel && !fname.empty()) { + EditorPanel::openPreviousEditorImage(); + return true; + } - break; // to avoid gcc complain + break; // to avoid gcc complain - case GDK_KEY_F4: // open next image from Editor's perspective - if (!simpleEditor && fPanel && !fname.empty()) { - EditorPanel::openNextEditorImage(); - return true; - } + case GDK_KEY_F4: // open next image from Editor's perspective + if (!simpleEditor && fPanel && !fname.empty()) { + EditorPanel::openNextEditorImage(); + return true; + } - break; // to avoid gcc complain + break; // to avoid gcc complain } } @@ -1678,7 +1751,7 @@ void EditorPanel::procParamsChanged (Thumbnail* thm, int whoChangedIt) } } -bool EditorPanel::idle_saveImage (ProgressConnector *pc, Glib::ustring fname, SaveFormat sf) +bool EditorPanel::idle_saveImage (ProgressConnector *pc, Glib::ustring fname, SaveFormat sf, rtengine::procparams::ProcParams &pparams) { rtengine::IImage16* img = pc->returnValue(); delete pc; @@ -1692,15 +1765,16 @@ bool EditorPanel::idle_saveImage (ProgressConnector *pc, Gl if (sf.format == "tif") ld->startFunc (sigc::bind (sigc::mem_fun (img, &rtengine::IImage16::saveAsTIFF), fname, sf.tiffBits, sf.tiffUncompressed), - sigc::bind (sigc::mem_fun (*this, &EditorPanel::idle_imageSaved), ld, img, fname, sf)); + sigc::bind (sigc::mem_fun (*this, &EditorPanel::idle_imageSaved), ld, img, fname, sf, pparams)); else if (sf.format == "png") - ld->startFunc (sigc::bind (sigc::mem_fun (img, &rtengine::IImage16::saveAsPNG), fname, sf.pngCompression, sf.pngBits), - sigc::bind (sigc::mem_fun (*this, &EditorPanel::idle_imageSaved), ld, img, fname, sf)); + ld->startFunc (sigc::bind (sigc::mem_fun (img, &rtengine::IImage16::saveAsPNG), fname, sf.pngBits), + sigc::bind (sigc::mem_fun (*this, &EditorPanel::idle_imageSaved), ld, img, fname, sf, pparams)); else if (sf.format == "jpg") ld->startFunc (sigc::bind (sigc::mem_fun (img, &rtengine::IImage16::saveAsJPEG), fname, sf.jpegQuality, sf.jpegSubSamp), - sigc::bind (sigc::mem_fun (*this, &EditorPanel::idle_imageSaved), ld, img, fname, sf)); - else + sigc::bind (sigc::mem_fun (*this, &EditorPanel::idle_imageSaved), ld, img, fname, sf, pparams)); + else { delete ld; + } } else { Glib::ustring msg_ = Glib::ustring ("") + fname + ": Error during image processing\n"; Gtk::MessageDialog msgd (*parent, msg_, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); @@ -1717,7 +1791,7 @@ bool EditorPanel::idle_saveImage (ProgressConnector *pc, Gl return false; } -bool EditorPanel::idle_imageSaved (ProgressConnector *pc, rtengine::IImage16* img, Glib::ustring fname, SaveFormat sf) +bool EditorPanel::idle_imageSaved (ProgressConnector *pc, rtengine::IImage16* img, Glib::ustring fname, SaveFormat sf, rtengine::procparams::ProcParams &pparams) { img->free (); @@ -1726,11 +1800,8 @@ bool EditorPanel::idle_imageSaved (ProgressConnector *pc, rtengine::IImage1 // save processing parameters, if needed if (sf.saveParams) { - rtengine::procparams::ProcParams pparams; - ipc->getParams (&pparams); // We keep the extension to avoid overwriting the profile when we have // the same output filename with different extension - //pparams.save (removeExtension (fname) + ".out" + paramFileExtension); pparams.save (fname + ".out" + paramFileExtension); } } else { @@ -1796,7 +1867,7 @@ void EditorPanel::saveAsPressed () fnameOut = saveAsDialog->getFileName (); options.lastSaveAsPath = saveAsDialog->getDirectory (); - saveAsDialog->get_size(options.saveAsDialogWidth, options.saveAsDialogHeight); + saveAsDialog->get_size (options.saveAsDialogWidth, options.saveAsDialogHeight); options.autoSuffix = saveAsDialog->getAutoSuffix (); options.saveMethodNum = saveAsDialog->getSaveMethodNum (); lastSaveAsFileName = Glib::path_get_basename (removeExtension (fnameOut)); @@ -1847,7 +1918,7 @@ void EditorPanel::saveAsPressed () ProgressConnector *ld = new ProgressConnector(); ld->startFunc (sigc::bind (sigc::ptr_fun (&rtengine::processImage), job, err, parent->getProgressListener(), options.tunnelMetaData, false ), - sigc::bind (sigc::mem_fun ( *this, &EditorPanel::idle_saveImage ), ld, fnameOut, sf )); + sigc::bind (sigc::mem_fun ( *this, &EditorPanel::idle_saveImage ), ld, fnameOut, sf, pparams)); saveimgas->set_sensitive (false); sendtogimp->set_sensitive (false); } @@ -1897,25 +1968,27 @@ void EditorPanel::sendToGimpPressed () } -bool EditorPanel::saveImmediately(const Glib::ustring &filename, const SaveFormat &sf) +bool EditorPanel::saveImmediately (const Glib::ustring &filename, const SaveFormat &sf) { rtengine::procparams::ProcParams pparams; ipc->getParams (&pparams); - rtengine::ProcessingJob *job = rtengine::ProcessingJob::create(ipc->getInitialImage(), pparams); + rtengine::ProcessingJob *job = rtengine::ProcessingJob::create (ipc->getInitialImage(), pparams); // save immediately - rtengine::IImage16 *img = rtengine::processImage(job, err, nullptr, options.tunnelMetaData, false); + rtengine::IImage16 *img = rtengine::processImage (job, err, nullptr, options.tunnelMetaData, false); int err = 0; + if (sf.format == "tif") { - err = img->saveAsTIFF(filename, sf.tiffBits, sf.tiffUncompressed); + err = img->saveAsTIFF (filename, sf.tiffBits, sf.tiffUncompressed); } else if (sf.format == "png") { - err = img->saveAsPNG(filename, sf.pngCompression, sf.pngBits); + err = img->saveAsPNG (filename, sf.pngBits); } else if (sf.format == "jpg") { - err = img->saveAsJPEG(filename, sf.jpegQuality, sf.jpegSubSamp); + err = img->saveAsJPEG (filename, sf.jpegQuality, sf.jpegSubSamp); } else { err = 1; } + img->free(); return !err; } @@ -1966,7 +2039,7 @@ bool EditorPanel::idle_sendToGimp ( ProgressConnector *pc, int tries = 1; while (Glib::file_test (fileName, Glib::FILE_TEST_EXISTS) && tries < 1000) { - fileName = Glib::ustring::compose("%1-%2.%3", fname, tries, sf.format); + fileName = Glib::ustring::compose ("%1-%2.%3", fname, tries, sf.format); tries++; } @@ -2012,9 +2085,9 @@ bool EditorPanel::idle_sentToGimp (ProgressConnector *pc, rtengine::IImage1 } if (!success) { - Gtk::MessageDialog msgd (*parent, M("MAIN_MSG_CANNOTSTARTEDITOR"), false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); - msgd.set_secondary_text (M("MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY")); - msgd.set_title (M("MAIN_BUTTON_SENDTOEDITOR")); + Gtk::MessageDialog msgd (*parent, M ("MAIN_MSG_CANNOTSTARTEDITOR"), false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); + msgd.set_secondary_text (M ("MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY")); + msgd.set_title (M ("MAIN_BUTTON_SENDTOEDITOR")); msgd.run (); } } @@ -2069,7 +2142,7 @@ void EditorPanel::beforeAfterToggled () if (beforeAfter->get_active ()) { int errorCode = 0; - rtengine::InitialImage *beforeImg = rtengine::InitialImage::load ( isrc->getImageSource ()->getFileName(), openThm->getType() == FT_Raw , &errorCode, nullptr); + rtengine::InitialImage *beforeImg = rtengine::InitialImage::load ( isrc->getImageSource ()->getFileName(), openThm->getType() == FT_Raw, &errorCode, nullptr); if ( !beforeImg || errorCode ) { return; @@ -2138,7 +2211,7 @@ void EditorPanel::tbBeforeLock_toggled () } void EditorPanel::histogramChanged (LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma, LUTu & histToneCurve, LUTu & histLCurve, LUTu & histCCurve, /*LUTu & histCLurve, LUTu & histLLCurve,*/ LUTu & histLCAM, LUTu & histCCAM, - LUTu & histRedRaw, LUTu & histGreenRaw, LUTu & histBlueRaw , LUTu & histChroma, LUTu & histLRETI) + LUTu & histRedRaw, LUTu & histGreenRaw, LUTu & histBlueRaw, LUTu & histChroma, LUTu & histLRETI) { if (histogramPanel) { @@ -2199,9 +2272,9 @@ void EditorPanel::tbShowHideSidePanels_managestate() ShowHideSidePanelsconn.block (false); } -void EditorPanel::updateProfiles(const Glib::ustring &printerProfile, rtengine::RenderingIntent printerIntent, bool printerBPC) +void EditorPanel::updateProfiles (const Glib::ustring &printerProfile, rtengine::RenderingIntent printerIntent, bool printerBPC) { - colorMgmtToolBar->canSoftProof(!printerProfile.empty() && printerProfile != "None"); + colorMgmtToolBar->canSoftProof (!printerProfile.empty() && printerProfile != "None"); } void EditorPanel::updateTPVScrollbar (bool hide) @@ -2218,64 +2291,64 @@ void EditorPanel::updateHistogramPosition (int oldPosition, int newPosition) { switch (newPosition) { - case 0: + case 0: - // No histogram - if (!oldPosition) { - // An histogram actually exist, we delete it - delete histogramPanel; - histogramPanel = nullptr; - } + // No histogram + if (!oldPosition) { + // An histogram actually exist, we delete it + delete histogramPanel; + histogramPanel = nullptr; + } - // else no need to create it - break; + // else no need to create it + break; - case 1: + case 1: - // Histogram on the left pane - if (oldPosition == 0) { - // There was no Histogram before, so we create it - histogramPanel = Gtk::manage (new HistogramPanel ()); - leftbox->pack_start (*histogramPanel, Gtk::PACK_SHRINK, 2); - } else if (oldPosition == 2) { - // The histogram was on the right side, so we move it to the left - histogramPanel->reference(); - removeIfThere (vboxright, histogramPanel, false); - leftbox->pack_start (*histogramPanel, Gtk::PACK_SHRINK, 2); - histogramPanel->unreference(); - } + // Histogram on the left pane + if (oldPosition == 0) { + // There was no Histogram before, so we create it + histogramPanel = Gtk::manage (new HistogramPanel ()); + leftbox->pack_start (*histogramPanel, Gtk::PACK_SHRINK, 2); + } else if (oldPosition == 2) { + // The histogram was on the right side, so we move it to the left + histogramPanel->reference(); + removeIfThere (vboxright, histogramPanel, false); + leftbox->pack_start (*histogramPanel, Gtk::PACK_SHRINK, 2); + histogramPanel->unreference(); + } - histogramPanel->reorder (Gtk::POS_LEFT); - leftbox->reorder_child (*histogramPanel, 0); - break; + histogramPanel->reorder (Gtk::POS_LEFT); + leftbox->reorder_child (*histogramPanel, 0); + break; - case 2: - default: + case 2: + default: - // Histogram on the right pane - if (oldPosition == 0) { - // There was no Histogram before, so we create it - histogramPanel = Gtk::manage (new HistogramPanel ()); - vboxright->pack_start (*histogramPanel, Gtk::PACK_SHRINK, 2); - } else if (oldPosition == 1) { - // The histogram was on the left side, so we move it to the right - histogramPanel->reference(); - removeIfThere (leftbox, histogramPanel, false); - vboxright->pack_start (*histogramPanel, Gtk::PACK_SHRINK, 2); - histogramPanel->unreference(); - } + // Histogram on the right pane + if (oldPosition == 0) { + // There was no Histogram before, so we create it + histogramPanel = Gtk::manage (new HistogramPanel ()); + vboxright->pack_start (*histogramPanel, Gtk::PACK_SHRINK, 2); + } else if (oldPosition == 1) { + // The histogram was on the left side, so we move it to the right + histogramPanel->reference(); + removeIfThere (leftbox, histogramPanel, false); + vboxright->pack_start (*histogramPanel, Gtk::PACK_SHRINK, 2); + histogramPanel->unreference(); + } - histogramPanel->reorder (Gtk::POS_RIGHT); - vboxright->reorder_child (*histogramPanel, 0); - break; + histogramPanel->reorder (Gtk::POS_RIGHT); + vboxright->reorder_child (*histogramPanel, 0); + break; } iareapanel->imageArea->setPointerMotionHListener (histogramPanel); } -void EditorPanel::defaultMonitorProfileChanged(const Glib::ustring &profile_name, bool auto_monitor_profile) +void EditorPanel::defaultMonitorProfileChanged (const Glib::ustring &profile_name, bool auto_monitor_profile) { - colorMgmtToolBar->defaultMonitorProfileChanged(profile_name, auto_monitor_profile); + colorMgmtToolBar->defaultMonitorProfileChanged (profile_name, auto_monitor_profile); } diff --git a/rtgui/editorpanel.h b/rtgui/editorpanel.h index d3d0eeaf7..5beb9ee7d 100644 --- a/rtgui/editorpanel.h +++ b/rtgui/editorpanel.h @@ -46,12 +46,12 @@ struct EditorPanelIdleHelper { class RTWindow; class EditorPanel final : - public Gtk::VBox, - public PParamsChangeListener, - public rtengine::ProgressListener, - public ThumbnailListener, - public HistoryBeforeLineListener, - public rtengine::HistogramListener + public Gtk::VBox, + public PParamsChangeListener, + public rtengine::ProgressListener, + public ThumbnailListener, + public HistoryBeforeLineListener, + public rtengine::HistogramListener { public: explicit EditorPanel (FilePanel* filePanel = nullptr); @@ -74,6 +74,7 @@ public: } void writeOptions(); + void writeToolExpandedStatus (std::vector &tpOpen); void showTopPanel (bool show); bool isRealized() @@ -130,14 +131,14 @@ public: { return isProcessing; } - void updateProfiles(const Glib::ustring &printerProfile, rtengine::RenderingIntent printerIntent, bool printerBPC); + void updateProfiles (const Glib::ustring &printerProfile, rtengine::RenderingIntent printerIntent, bool printerBPC); void updateTPVScrollbar (bool hide); void updateTabsUsesIcons (bool useIcons); void updateHistogramPosition (int oldPosition, int newPosition); - void defaultMonitorProfileChanged(const Glib::ustring &profile_name, bool auto_monitor_profile); + void defaultMonitorProfileChanged (const Glib::ustring &profile_name, bool auto_monitor_profile); - bool saveImmediately(const Glib::ustring &filename, const SaveFormat &sf); + bool saveImmediately (const Glib::ustring &filename, const SaveFormat &sf); Gtk::Paned* catalogPane; @@ -145,8 +146,8 @@ private: void close (); BatchQueueEntry* createBatchQueueEntry (); - bool idle_imageSaved (ProgressConnector *pc, rtengine::IImage16* img, Glib::ustring fname, SaveFormat sf); - bool idle_saveImage (ProgressConnector *pc, Glib::ustring fname, SaveFormat sf); + bool idle_imageSaved (ProgressConnector *pc, rtengine::IImage16* img, Glib::ustring fname, SaveFormat sf, rtengine::procparams::ProcParams &pparams); + bool idle_saveImage (ProgressConnector *pc, Glib::ustring fname, SaveFormat sf, rtengine::procparams::ProcParams &pparams); bool idle_sendToGimp ( ProgressConnector *pc, Glib::ustring fname); bool idle_sentToGimp (ProgressConnector *pc, rtengine::IImage16* img, Glib::ustring filename); @@ -211,6 +212,8 @@ private: Thumbnail* openThm; // may get invalid on external delete event Glib::ustring fname; // must be saved separately + int selectedFrame; + rtengine::InitialImage* isrc; rtengine::StagedImageProcessor* ipc; rtengine::StagedImageProcessor* beforeIpc; // for the before-after view diff --git a/rtgui/epd.cc b/rtgui/epd.cc index d7848aee0..602585dfb 100644 --- a/rtgui/epd.cc +++ b/rtgui/epd.cc @@ -182,3 +182,11 @@ void EdgePreservingDecompositionUI::setBatchMode(bool batchMode) reweightingIterates->showEditedCB(); } +void EdgePreservingDecompositionUI::setAdjusterBehavior (bool stAdd, bool gAdd, bool esAdd, bool scAdd, bool rAdd) +{ + strength->setAddMode(stAdd); + gamma->setAddMode(gAdd); + edgeStopping->setAddMode(esAdd); + scale->setAddMode(scAdd); + reweightingIterates->setAddMode(rAdd); +} diff --git a/rtgui/epd.h b/rtgui/epd.h index c9fc5d0af..2e18cc0c9 100644 --- a/rtgui/epd.h +++ b/rtgui/epd.h @@ -43,6 +43,7 @@ public: void adjusterChanged (Adjuster* a, double newval); void enabledChanged (); + void setAdjusterBehavior (bool stAdd, bool gAdd, bool esAdd, bool scAdd, bool rAdd); }; #endif diff --git a/rtgui/exifpanel.cc b/rtgui/exifpanel.cc index 34cb2c064..da2659a4f 100644 --- a/rtgui/exifpanel.cc +++ b/rtgui/exifpanel.cc @@ -25,44 +25,50 @@ using namespace rtengine; using namespace rtengine::procparams; using namespace rtexif; -ExifPanel::ExifPanel () : idata(nullptr) +ExifPanel::ExifPanel () : idata (nullptr) { recursiveOp = true; - exifTree = Gtk::manage(new Gtk::TreeView()); - scrolledWindow = Gtk::manage(new Gtk::ScrolledWindow()); + exifTree = Gtk::manage (new Gtk::TreeView()); + scrolledWindow = Gtk::manage (new Gtk::ScrolledWindow()); - exifTree->set_headers_visible(false); - exifTree->set_rules_hint(false); - exifTree->set_reorderable(false); - exifTree->set_enable_search(true); + exifTree->set_headers_visible (false); + exifTree->set_rules_hint (false); + exifTree->set_reorderable (false); + exifTree->set_enable_search (true); exifTree->get_selection()->set_mode (Gtk::SELECTION_MULTIPLE); - scrolledWindow->set_shadow_type(Gtk::SHADOW_NONE); - scrolledWindow->set_policy(Gtk::POLICY_ALWAYS, Gtk::POLICY_ALWAYS); - scrolledWindow->property_window_placement().set_value(Gtk::CORNER_TOP_LEFT); - scrolledWindow->add(*exifTree); + scrolledWindow->set_shadow_type (Gtk::SHADOW_NONE); + scrolledWindow->set_policy (Gtk::POLICY_ALWAYS, Gtk::POLICY_ALWAYS); + scrolledWindow->property_window_placement().set_value (Gtk::CORNER_TOP_LEFT); + scrolledWindow->add (*exifTree); - exifTreeModel = Gtk::TreeStore::create(exifColumns); + exifTreeModel = Gtk::TreeStore::create (exifColumns); exifTree->set_model (exifTreeModel); + exifTree->set_grid_lines (Gtk::TREE_VIEW_GRID_LINES_NONE); + exifTree->set_row_separator_func ( + [&] (const Glib::RefPtr& model, const Gtk::TreeModel::iterator & row) { + return row->get_value (exifColumns.isSeparator); + } + ); delicon = RTImage::createFromFile ("gtk-close.png"); keepicon = RTImage::createFromFile ("gtk-apply.png"); editicon = RTImage::createFromFile ("gtk-add.png"); - Gtk::TreeView::Column *viewcol = Gtk::manage(new Gtk::TreeView::Column ("Field Name")); - Gtk::CellRendererPixbuf* render_pb = Gtk::manage(new Gtk::CellRendererPixbuf ()); - Gtk::CellRendererText *render_txt = Gtk::manage(new Gtk::CellRendererText()); + Gtk::TreeView::Column *viewcol = Gtk::manage (new Gtk::TreeView::Column ("Field Name")); + Gtk::CellRendererPixbuf* render_pb = Gtk::manage (new Gtk::CellRendererPixbuf ()); + Gtk::CellRendererText *render_txt = Gtk::manage (new Gtk::CellRendererText()); render_txt->property_ellipsize() = Pango::ELLIPSIZE_END; viewcol->pack_start (*render_pb, false); viewcol->pack_start (*render_txt, true); viewcol->add_attribute (*render_pb, "pixbuf", exifColumns.icon); viewcol->add_attribute (*render_txt, "markup", exifColumns.field); - viewcol->set_expand(true); + viewcol->set_expand (true); viewcol->set_resizable (true); - viewcol->set_fixed_width(35); - viewcol->set_min_width(35); - viewcol->set_sizing(Gtk::TREE_VIEW_COLUMN_AUTOSIZE); + viewcol->set_fixed_width (35); + viewcol->set_min_width (35); + viewcol->set_sizing (Gtk::TREE_VIEW_COLUMN_AUTOSIZE); render_pb->property_ypad() = 0; render_txt->property_ypad() = 0; @@ -71,16 +77,16 @@ ExifPanel::ExifPanel () : idata(nullptr) exifTree->append_column (*viewcol); - Gtk::TreeView::Column *viewcolv = Gtk::manage(new Gtk::TreeView::Column ("Value")); - Gtk::CellRendererText *render_txtv = Gtk::manage(new Gtk::CellRendererText()); + Gtk::TreeView::Column *viewcolv = Gtk::manage (new Gtk::TreeView::Column ("Value")); + Gtk::CellRendererText *render_txtv = Gtk::manage (new Gtk::CellRendererText()); render_txtv->property_ellipsize() = Pango::ELLIPSIZE_END; viewcolv->pack_start (*render_txtv, true); viewcolv->add_attribute (*render_txtv, "markup", exifColumns.value); - viewcolv->set_expand(true); + viewcolv->set_expand (true); viewcolv->set_resizable (true); - viewcol->set_fixed_width(35); - viewcolv->set_min_width(35); - viewcolv->set_sizing(Gtk::TREE_VIEW_COLUMN_AUTOSIZE); + viewcol->set_fixed_width (35); + viewcolv->set_min_width (35); + viewcolv->set_sizing (Gtk::TREE_VIEW_COLUMN_AUTOSIZE); render_txtv->property_ypad() = 0; @@ -88,61 +94,69 @@ ExifPanel::ExifPanel () : idata(nullptr) pack_start (*scrolledWindow); - Gtk::Grid* buttons1 = Gtk::manage(new Gtk::Grid()); - buttons1->set_row_homogeneous(true); - buttons1->set_column_homogeneous(true); - setExpandAlignProperties(buttons1, false, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - Gtk::Grid* buttons2 = Gtk::manage(new Gtk::Grid()); - buttons2->set_row_homogeneous(true); - buttons2->set_column_homogeneous(true); - setExpandAlignProperties(buttons2, false, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + Gtk::Grid* buttons1 = Gtk::manage (new Gtk::Grid()); + buttons1->set_row_homogeneous (true); + buttons1->set_column_homogeneous (true); + setExpandAlignProperties (buttons1, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + Gtk::Grid* buttons2 = Gtk::manage (new Gtk::Grid()); + buttons2->set_row_homogeneous (true); + buttons2->set_column_homogeneous (true); + setExpandAlignProperties (buttons2, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - remove = Gtk::manage(new Gtk::Button ()); // M("EXIFPANEL_REMOVE") - remove->set_image (*Gtk::manage(new Gtk::Image (delicon))); - remove->set_tooltip_text (M("EXIFPANEL_REMOVEHINT")); - remove->get_style_context()->add_class("Left"); - setExpandAlignProperties(remove, true, true, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); - buttons1->attach_next_to(*remove, Gtk::POS_LEFT, 1, 1); + remove = Gtk::manage (new Gtk::Button ()); // M("EXIFPANEL_REMOVE") + remove->set_image (*Gtk::manage (new Gtk::Image (delicon))); + remove->set_tooltip_text (M ("EXIFPANEL_REMOVEHINT")); + remove->get_style_context()->add_class ("Left"); + setExpandAlignProperties (remove, true, true, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); + buttons1->attach_next_to (*remove, Gtk::POS_LEFT, 1, 1); - keep = Gtk::manage(new Gtk::Button ()); // M("EXIFPANEL_KEEP") - keep->set_image (*Gtk::manage(new Gtk::Image (keepicon))); - keep->set_tooltip_text (M("EXIFPANEL_KEEPHINT")); - keep->get_style_context()->add_class("MiddleH"); - setExpandAlignProperties(keep, true, true, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); - buttons1->attach_next_to(*keep, Gtk::POS_RIGHT, 1, 1); + keep = Gtk::manage (new Gtk::Button ()); // M("EXIFPANEL_KEEP") + keep->set_image (*Gtk::manage (new Gtk::Image (keepicon))); + keep->set_tooltip_text (M ("EXIFPANEL_KEEPHINT")); + keep->get_style_context()->add_class ("MiddleH"); + setExpandAlignProperties (keep, true, true, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); + buttons1->attach_next_to (*keep, Gtk::POS_RIGHT, 1, 1); - add = Gtk::manage(new Gtk::Button ()); // M("EXIFPANEL_ADDEDIT") - add->set_image (*Gtk::manage(new Gtk::Image (editicon))); - add->set_tooltip_text (M("EXIFPANEL_ADDEDITHINT")); - add->get_style_context()->add_class("Right"); - setExpandAlignProperties(add, true, true, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); - buttons1->attach_next_to(*add, Gtk::POS_RIGHT, 1, 1); + add = Gtk::manage (new Gtk::Button ()); // M("EXIFPANEL_ADDEDIT") + add->set_image (*Gtk::manage (new Gtk::Image (editicon))); + add->set_tooltip_text (M ("EXIFPANEL_ADDEDITHINT")); + add->get_style_context()->add_class ("Right"); + setExpandAlignProperties (add, true, true, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); + buttons1->attach_next_to (*add, Gtk::POS_RIGHT, 1, 1); - reset = Gtk::manage(new Gtk::Button ()); // M("EXIFPANEL_RESET") - reset->set_image (*Gtk::manage(new RTImage ("gtk-undo-ltr.png", "gtk-undo-rtl.png"))); - reset->set_tooltip_text (M("EXIFPANEL_RESETHINT")); - reset->get_style_context()->add_class("Left"); - setExpandAlignProperties(reset, true, true, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); - buttons2->attach_next_to(*reset, Gtk::POS_LEFT, 1, 1); + showAll = Gtk::manage (new Gtk::ToggleButton (M ("EXIFPANEL_SHOWALL"))); + //add->set_tooltip_text (M("EXIFPANEL_SHOWALL")); + showAll->get_style_context()->add_class ("Left"); + setExpandAlignProperties (showAll, false, true, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); + showAll->set_active (options.lastShowAllExif); + buttons2->attach_next_to (*showAll, Gtk::POS_LEFT, 1, 1); - resetAll = Gtk::manage(new Gtk::Button ()); // M("EXIFPANEL_RESETALL") - resetAll->set_image (*Gtk::manage(new RTImage ("gtk-undoall-ltr.png", "gtk-undoall-rtl.png"))); - resetAll->set_tooltip_text (M("EXIFPANEL_RESETALLHINT")); - resetAll->get_style_context()->add_class("Right"); - setExpandAlignProperties(resetAll, false, false, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); - buttons2->attach_next_to(*resetAll, Gtk::POS_RIGHT, 1, 1); + reset = Gtk::manage (new Gtk::Button ()); // M("EXIFPANEL_RESET") + reset->set_image (*Gtk::manage (new RTImage ("gtk-undo-ltr.png", "gtk-undo-rtl.png"))); + reset->set_tooltip_text (M ("EXIFPANEL_RESETHINT")); + reset->get_style_context()->add_class ("MiddleH"); + setExpandAlignProperties (reset, true, true, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); + buttons2->attach_next_to (*reset, Gtk::POS_RIGHT, 1, 1); + + resetAll = Gtk::manage (new Gtk::Button ()); // M("EXIFPANEL_RESETALL") + resetAll->set_image (*Gtk::manage (new RTImage ("gtk-undoall-ltr.png", "gtk-undoall-rtl.png"))); + resetAll->set_tooltip_text (M ("EXIFPANEL_RESETALLHINT")); + resetAll->get_style_context()->add_class ("Right"); + setExpandAlignProperties (resetAll, false, false, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); + buttons2->attach_next_to (*resetAll, Gtk::POS_RIGHT, 1, 1); pack_end (*buttons2, Gtk::PACK_SHRINK); pack_end (*buttons1, Gtk::PACK_SHRINK); - exifTree->get_selection()->signal_changed().connect(sigc::mem_fun(*this, &ExifPanel::exifSelectionChanged)); - exifTree->signal_row_activated().connect(sigc::mem_fun(*this, &ExifPanel::row_activated)); + exifTree->get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ExifPanel::exifSelectionChanged)); + exifTree->signal_row_activated().connect (sigc::mem_fun (*this, &ExifPanel::row_activated)); - remove->signal_clicked().connect( sigc::mem_fun(*this, &ExifPanel::removePressed) ); - keep->signal_clicked().connect( sigc::mem_fun(*this, &ExifPanel::keepPressed) ); - reset->signal_clicked().connect( sigc::mem_fun(*this, &ExifPanel::resetPressed) ); - resetAll->signal_clicked().connect( sigc::mem_fun(*this, &ExifPanel::resetAllPressed) ); - add->signal_clicked().connect( sigc::mem_fun(*this, &ExifPanel::addPressed) ); + remove->signal_clicked().connect ( sigc::mem_fun (*this, &ExifPanel::removePressed) ); + keep->signal_clicked().connect ( sigc::mem_fun (*this, &ExifPanel::keepPressed) ); + reset->signal_clicked().connect ( sigc::mem_fun (*this, &ExifPanel::resetPressed) ); + resetAll->signal_clicked().connect ( sigc::mem_fun (*this, &ExifPanel::resetAllPressed) ); + add->signal_clicked().connect ( sigc::mem_fun (*this, &ExifPanel::addPressed) ); + showAll->signal_toggled().connect ( sigc::mem_fun (*this, &ExifPanel::showAlltoggled) ); show_all (); } @@ -177,22 +191,25 @@ void ExifPanel::setDefaults (const ProcParams* defParams, const ParamsEdited* pe defChangeList = defParams->exif; } -void ExifPanel::setImageData (const ImageMetaData* id) +void ExifPanel::setImageData (const FramesMetaData* id) { idata = id; exifTreeModel->clear (); - if (id && id->getExifData ()) { -// id->getExifData ()->printAll (); - addDirectory (id->getExifData (), exifTreeModel->children()); + if (idata) { + for (unsigned int rootNum = 0; rootNum < id->getRootCount (); ++rootNum) { + if ( id->getRootExifData (rootNum)) { + addDirectory (id->getRootExifData (rootNum), exifTreeModel->children(), rootNum > 0); + } + } } } Gtk::TreeModel::Children ExifPanel::addTag (const Gtk::TreeModel::Children& root, Glib::ustring field, Glib::ustring value, rtexif::ActionCode action, bool editable) { - Gtk::TreeModel::Row row = *(exifTreeModel->append(root)); + Gtk::TreeModel::Row row = * (exifTreeModel->append (root)); row[exifColumns.action] = action; row[exifColumns.editable] = editable; row[exifColumns.edited] = false; @@ -207,36 +224,74 @@ Gtk::TreeModel::Children ExifPanel::addTag (const Gtk::TreeModel::Children& root } if (editable) { - row[exifColumns.field] = Glib::ustring("") + escapeHtmlChars(field) + ""; - row[exifColumns.value] = Glib::ustring("") + escapeHtmlChars(value) + ""; + row[exifColumns.field] = Glib::ustring ("") + escapeHtmlChars (field) + ""; + row[exifColumns.value] = Glib::ustring ("") + escapeHtmlChars (value) + ""; } else if (action == AC_SYSTEM) { - row[exifColumns.field] = Glib::ustring("") + escapeHtmlChars(field) + ""; - row[exifColumns.value] = Glib::ustring("") + escapeHtmlChars(value) + ""; + row[exifColumns.field] = Glib::ustring ("") + escapeHtmlChars (field) + ""; + row[exifColumns.value] = Glib::ustring ("") + escapeHtmlChars (value) + ""; } else { - row[exifColumns.field] = escapeHtmlChars(field); - row[exifColumns.value] = escapeHtmlChars(value); + row[exifColumns.field] = escapeHtmlChars (field); + row[exifColumns.value] = escapeHtmlChars (value); } return row.children(); } -void ExifPanel::addDirectory (const TagDirectory* dir, Gtk::TreeModel::Children root) +Gtk::TreeModel::Children ExifPanel::addSeparator () { - for (int i = 0; i < dir->getCount(); i++) { - Tag* t = (const_cast(dir))->getTagByIndex (i); + Gtk::TreeModel::Row row = * (exifTreeModel->append (exifTreeModel->children())); + row[exifColumns.action] = rtexif::ActionCode::AC_INVALID; + row[exifColumns.editable] = false; + row[exifColumns.edited] = false; + row[exifColumns.field_nopango] = ""; + row[exifColumns.value_nopango] = ""; + row[exifColumns.orig_value] = ""; + row[exifColumns.isSeparator] = true; - if (t->getAttrib() && t->getAttrib()->action == AC_SYSTEM) { + return row.children(); +} + +void ExifPanel::addDirectory (const TagDirectory* dir, Gtk::TreeModel::Children root, bool checkForSeparator) +{ + + for (int i = 0; i < dir->getCount(); ++i) { + Tag* t = (const_cast (dir))->getTagByIndex (i); + + bool hasContent = false; + + if (checkForSeparator && i == 0) { + for (int j = 0; j < dir->getCount(); ++j) { + Tag* t2 = (const_cast (dir))->getTagByIndex (j); + const TagAttrib* currAttrib = t2->getAttrib(); + + if (currAttrib && ((options.lastShowAllExif) || (!options.lastShowAllExif && currAttrib->action != AC_SYSTEM))) { + addSeparator(); + hasContent = true; + break; + } + } + } else { + hasContent = true; + } + + if (!hasContent) { + return; + } + + const TagAttrib* currAttrib = t->getAttrib(); + + if (!options.lastShowAllExif && currAttrib && currAttrib->action == AC_SYSTEM) { continue; } - if (t->isDirectory()) - for (int j = 0; t->getDirectory(j); j++) { - Gtk::TreeModel::Children ch = addTag (root, t->nameToString (j), M("EXIFPANEL_SUBDIRECTORY"), t->getAttrib() ? t->getAttrib()->action : AC_DONTWRITE, t->getAttrib() && t->getAttrib()->editable); - addDirectory (t->getDirectory(j), ch); + if (t->isDirectory()) { + for (int j = 0; t->getDirectory (j); j++) { + Gtk::TreeModel::Children ch = addTag (root, t->nameToString (j), M ("EXIFPANEL_SUBDIRECTORY"), currAttrib ? currAttrib->action : AC_DONTWRITE, currAttrib && currAttrib->editable); + addDirectory (t->getDirectory (j), ch); } - else { - addTag (root, t->nameToString (), t->valueToString (), t->getAttrib() ? (t->getOwnMemory() ? t->getAttrib()->action : AC_SYSTEM) : AC_DONTWRITE, t->getAttrib() && t->getAttrib()->editable); + } else { + addTag (root, t->nameToString (), t->valueToString (), currAttrib ? (t->getOwnMemory() ? currAttrib->action : AC_SYSTEM) : AC_DONTWRITE, currAttrib && currAttrib->editable); } } } @@ -262,11 +317,11 @@ void ExifPanel::exifSelectionChanged () remove->set_sensitive (1); keep->set_sensitive (1); reset->set_sensitive (1); - } else if (iter->get_value(exifColumns.icon) == delicon) { + } else if (iter->get_value (exifColumns.icon) == delicon) { remove->set_sensitive (0); keep->set_sensitive (1); reset->set_sensitive (1); - } else if (iter->get_value(exifColumns.icon) == keepicon || iter->get_value(exifColumns.icon) == editicon) { + } else if (iter->get_value (exifColumns.icon) == keepicon || iter->get_value (exifColumns.icon) == editicon) { keep->set_sensitive (0); remove->set_sensitive (1); reset->set_sensitive (1); @@ -371,8 +426,8 @@ Gtk::TreeModel::iterator ExifPanel::resetIt (Gtk::TreeModel::iterator iter) } if (iter->get_value (exifColumns.edited)) { - iter->set_value (exifColumns.value, Glib::ustring("") + iter->get_value(exifColumns.orig_value) + ""); - iter->set_value (exifColumns.value_nopango, iter->get_value(exifColumns.orig_value)); + iter->set_value (exifColumns.value, Glib::ustring ("") + iter->get_value (exifColumns.orig_value) + ""); + iter->set_value (exifColumns.value_nopango, iter->get_value (exifColumns.orig_value)); iter->set_value (exifColumns.edited, false); } @@ -415,14 +470,14 @@ void ExifPanel::resetAllPressed () void ExifPanel::addPressed () { - Gtk::Dialog* dialog = new Gtk::Dialog (M("EXIFPANEL_ADDTAGDLG_TITLE"), *((Gtk::Window*)get_toplevel()), true); + Gtk::Dialog* dialog = new Gtk::Dialog (M ("EXIFPANEL_ADDTAGDLG_TITLE"), * ((Gtk::Window*)get_toplevel()), true); dialog->add_button (Gtk::Stock::OK, Gtk::RESPONSE_OK); dialog->add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); Gtk::HBox* hb1 = new Gtk::HBox (); Gtk::HBox* hb2 = new Gtk::HBox (); - Gtk::Label* tlabel = new Gtk::Label (M("EXIFPANEL_ADDTAGDLG_SELECTTAG") + ":"); + Gtk::Label* tlabel = new Gtk::Label (M ("EXIFPANEL_ADDTAGDLG_SELECTTAG") + ":"); MyComboBoxText* tcombo = new MyComboBoxText (); tcombo->append ("Artist"); @@ -433,7 +488,7 @@ void ExifPanel::addPressed () hb1->pack_start (*tlabel, Gtk::PACK_SHRINK, 4); hb1->pack_start (*tcombo); - Gtk::Label* vlabel = new Gtk::Label (M("EXIFPANEL_ADDTAGDLG_ENTERVALUE") + ":"); + Gtk::Label* vlabel = new Gtk::Label (M ("EXIFPANEL_ADDTAGDLG_ENTERVALUE") + ":"); Gtk::Entry* ventry = new Gtk::Entry (); hb2->pack_start (*vlabel, Gtk::PACK_SHRINK, 4); hb2->pack_start (*ventry); @@ -479,6 +534,12 @@ void ExifPanel::addPressed () delete hb2; } +void ExifPanel::showAlltoggled () +{ + options.lastShowAllExif = showAll->get_active(); + setImageData (idata); +} + void ExifPanel::editTag (Gtk::TreeModel::Children root, Glib::ustring name, Glib::ustring value) { @@ -493,29 +554,30 @@ void ExifPanel::editTag (Gtk::TreeModel::Children root, Glib::ustring name, Glib } if (iter == root.end() && value != "#keep" && value != "#delete") { - iter = exifTreeModel->append(root); + iter = exifTreeModel->append (root); iter->set_value (exifColumns.field_nopango, fseg); iter->set_value (exifColumns.action, AC_INVALID); if (dp == Glib::ustring::npos) { - iter->set_value (exifColumns.value, Glib::ustring("") + value + ""); + iter->set_value (exifColumns.value, Glib::ustring ("") + value + ""); iter->set_value (exifColumns.value_nopango, value); iter->set_value (exifColumns.orig_value, value); - iter->set_value (exifColumns.field, Glib::ustring("") + fseg + ""); + iter->set_value (exifColumns.field, Glib::ustring ("") + fseg + ""); iter->set_value (exifColumns.edited, true); iter->set_value (exifColumns.editable, true); iter->set_value (exifColumns.icon, editicon); } else { - iter->set_value (exifColumns.value, Glib::ustring(M("EXIFPANEL_SUBDIRECTORY"))); - iter->set_value (exifColumns.value_nopango, Glib::ustring(M("EXIFPANEL_SUBDIRECTORY"))); + iter->set_value (exifColumns.value, Glib::ustring (M ("EXIFPANEL_SUBDIRECTORY"))); + iter->set_value (exifColumns.value_nopango, Glib::ustring (M ("EXIFPANEL_SUBDIRECTORY"))); iter->set_value (exifColumns.field, fseg); iter->set_value (exifColumns.icon, keepicon); - iter->set_value (exifColumns.orig_value, Glib::ustring(M("EXIFPANEL_SUBDIRECTORY"))); + iter->set_value (exifColumns.orig_value, Glib::ustring (M ("EXIFPANEL_SUBDIRECTORY"))); } } - if (iter == root.end()) + if (iter == root.end()) { return; + } if (dp == Glib::ustring::npos) { if (value == "#keep" && iter->get_value (exifColumns.action) != AC_SYSTEM) { @@ -523,7 +585,7 @@ void ExifPanel::editTag (Gtk::TreeModel::Children root, Glib::ustring name, Glib } else if (value == "#delete" && iter->get_value (exifColumns.action) != AC_SYSTEM) { iter->set_value (exifColumns.icon, delicon); } else { - iter->set_value (exifColumns.value, Glib::ustring("") + value + ""); + iter->set_value (exifColumns.value, Glib::ustring ("") + value + ""); iter->set_value (exifColumns.value_nopango, value); iter->set_value (exifColumns.edited, true); iter->set_value (exifColumns.icon, editicon); @@ -571,11 +633,11 @@ Glib::ustring ExifPanel::getSelection (bool onlyeditable) while (iter) { if (first) { ret = iter->get_value (exifColumns.field_nopango); + editable = iter->get_value (exifColumns.editable); } else { ret = iter->get_value (exifColumns.field_nopango) + "." + ret; } - editable = iter->get_value (exifColumns.editable); iter = iter->parent (); first = false; } @@ -637,8 +699,7 @@ void ExifPanel::row_activated (const Gtk::TreeModel::Path& path, Gtk::TreeViewCo exifTree->collapse_row (path); } else { exifTree->expand_row (path, false); - } - else if (iter->get_value (exifColumns.editable)) { + } else if (iter->get_value (exifColumns.editable)) { addPressed (); } } @@ -649,6 +710,6 @@ void ExifPanel::notifyListener () { if (listener) { - listener->panelChanged (EvExif, M("HISTORY_CHANGED")); + listener->panelChanged (EvExif, M ("HISTORY_CHANGED")); } } diff --git a/rtgui/exifpanel.h b/rtgui/exifpanel.h index 6244c1a4f..b9d76f25d 100644 --- a/rtgui/exifpanel.h +++ b/rtgui/exifpanel.h @@ -26,7 +26,7 @@ class ExifPanel : public Gtk::VBox, public ToolPanel { private: - const rtengine::ImageMetaData* idata; + const rtengine::FramesMetaData* idata; rtengine::procparams::ExifPairs changeList; rtengine::procparams::ExifPairs defChangeList; bool recursiveOp; @@ -43,18 +43,20 @@ private: Gtk::TreeModelColumn action; Gtk::TreeModelColumn editable; Gtk::TreeModelColumn edited; + Gtk::TreeModelColumn isSeparator; ExifColumns() { - add(field); - add(value); - add(icon); - add(action); - add(edited); - add(field_nopango); - add(value_nopango); - add(editable); - add(orig_value); + add (field); + add (value); + add (icon); + add (action); + add (edited); + add (field_nopango); + add (value_nopango); + add (editable); + add (orig_value); + add (isSeparator); } }; Glib::RefPtr delicon; @@ -71,37 +73,41 @@ private: Gtk::Button* add; Gtk::Button* reset; Gtk::Button* resetAll; + Gtk::ToggleButton* showAll; - Gtk::TreeModel::Children addTag (const Gtk::TreeModel::Children& root, Glib::ustring field, Glib::ustring value, rtexif::ActionCode action, bool editable); + Gtk::TreeModel::Children addTag (const Gtk::TreeModel::Children& root, Glib::ustring field, Glib::ustring value, rtexif::ActionCode action, bool editable); void editTag (Gtk::TreeModel::Children root, Glib::ustring name, Glib::ustring value); void updateChangeList (Gtk::TreeModel::Children root, std::string prefix); - void addDirectory (const rtexif::TagDirectory* dir, Gtk::TreeModel::Children root); + void addDirectory (const rtexif::TagDirectory* dir, Gtk::TreeModel::Children root, bool checkForSeparator = false); + Gtk::TreeModel::Children addSeparator(); Glib::ustring getSelection (bool onlyifeditable = false); - Glib::ustring getSelectedValue (); - void updateChangeList (); - void applyChangeList (); - void keepIt (Gtk::TreeModel::iterator iter); - void delIt (Gtk::TreeModel::iterator iter); + Glib::ustring getSelectedValue(); + void updateChangeList(); + void applyChangeList(); + void keepIt (Gtk::TreeModel::iterator iter); + void delIt (Gtk::TreeModel::iterator iter); Gtk::TreeModel::iterator resetIt (Gtk::TreeModel::iterator iter); + void removePressed(); + void keepPressed(); + void resetPressed(); + void resetAllPressed(); + void addPressed(); + void showAlltoggled(); + public: ExifPanel (); - virtual ~ExifPanel (); + virtual ~ExifPanel(); - void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr); - void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr); - void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr); + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr); - void setImageData (const rtengine::ImageMetaData* id); + void setImageData (const rtengine::FramesMetaData* id); - void exifSelectionChanged (); - void removePressed (); - void keepPressed (); - void resetPressed (); - void resetAllPressed (); - void addPressed (); + void exifSelectionChanged(); void row_activated (const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* column); - void notifyListener (); + void notifyListener(); }; diff --git a/rtgui/exportpanel.cc b/rtgui/exportpanel.cc index 72cf30fdd..7fdc3ae50 100644 --- a/rtgui/exportpanel.cc +++ b/rtgui/exportpanel.cc @@ -32,193 +32,193 @@ ExportPanel::ExportPanel () : listener (nullptr) pack_start(*enabled, Gtk::PACK_SHRINK, 4); pack_start (*Gtk::manage(new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 2);*/ - Gtk::Label* labExportTitle = Gtk::manage ( new Gtk::Label (M("EXPORT_FASTEXPORTOPTIONS")) ); + Gtk::Label* labExportTitle = Gtk::manage ( new Gtk::Label (M ("EXPORT_FASTEXPORTOPTIONS")) ); labExportTitle->set_use_markup (true); - labExportTitle->set_tooltip_text (M("EXPORT_INSTRUCTIONS")); - labExportTitle->set_alignment(Gtk::ALIGN_START); - pack_start(*labExportTitle, Gtk::PACK_SHRINK, 4); + labExportTitle->set_tooltip_text (M ("EXPORT_INSTRUCTIONS")); + labExportTitle->set_alignment (Gtk::ALIGN_START); + pack_start (*labExportTitle, Gtk::PACK_SHRINK, 4); Gtk::RadioButton::Group pipeline_group; - use_fast_pipeline = Gtk::manage ( new Gtk::RadioButton (pipeline_group, M("EXPORT_USE_FAST_PIPELINE"))); - use_normal_pipeline = Gtk::manage ( new Gtk::RadioButton (pipeline_group, M("EXPORT_USE_NORMAL_PIPELINE"))); - bypass_box = Gtk::manage(new Gtk::VBox()); - bypass_ALL = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_ALL"))); - use_fast_pipeline->set_tooltip_text(M("EXPORT_USE_FAST_PIPELINE_TIP")); - bypass_sharpening = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_SHARPENING"))); - bypass_sharpenEdge = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_SHARPENEDGE"))); - bypass_sharpenMicro = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_SHARPENMICRO"))); + use_fast_pipeline = Gtk::manage ( new Gtk::RadioButton (pipeline_group, M ("EXPORT_USE_FAST_PIPELINE"))); + use_normal_pipeline = Gtk::manage ( new Gtk::RadioButton (pipeline_group, M ("EXPORT_USE_NORMAL_PIPELINE"))); + bypass_box = Gtk::manage (new Gtk::VBox()); + bypass_ALL = Gtk::manage ( new Gtk::CheckButton (M ("EXPORT_BYPASS_ALL"))); + use_fast_pipeline->set_tooltip_text (M ("EXPORT_USE_FAST_PIPELINE_TIP")); + bypass_sharpening = Gtk::manage ( new Gtk::CheckButton (M ("EXPORT_BYPASS_SHARPENING"))); + bypass_sharpenEdge = Gtk::manage ( new Gtk::CheckButton (M ("EXPORT_BYPASS_SHARPENEDGE"))); + bypass_sharpenMicro = Gtk::manage ( new Gtk::CheckButton (M ("EXPORT_BYPASS_SHARPENMICRO"))); //bypass_lumaDenoise = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_LUMADENOISE"))); //bypass_colorDenoise = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_COLORDENOISE"))); - bypass_defringe = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_DEFRINGE"))); - bypass_dirpyrDenoise = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_DIRPYRDENOISE"))); - bypass_sh_hq = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_SH_HQ"))); - bypass_dirpyrequalizer = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_DIRPYREQUALIZER"))); - bypass_wavelet = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_EQUALIZER"))); - bypass_raw_ccSteps = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_RAW_CCSTEPS"))); - bypass_raw_ca = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_RAW_CA"))); - bypass_raw_df = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_RAW_DF"))); - bypass_raw_ff = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_RAW_FF"))); + bypass_defringe = Gtk::manage ( new Gtk::CheckButton (M ("EXPORT_BYPASS_DEFRINGE"))); + bypass_dirpyrDenoise = Gtk::manage ( new Gtk::CheckButton (M ("EXPORT_BYPASS_DIRPYRDENOISE"))); + bypass_sh_hq = Gtk::manage ( new Gtk::CheckButton (M ("EXPORT_BYPASS_SH_HQ"))); + bypass_dirpyrequalizer = Gtk::manage ( new Gtk::CheckButton (M ("EXPORT_BYPASS_DIRPYREQUALIZER"))); + bypass_wavelet = Gtk::manage ( new Gtk::CheckButton (M ("EXPORT_BYPASS_EQUALIZER"))); + bypass_raw_ccSteps = Gtk::manage ( new Gtk::CheckButton (M ("EXPORT_BYPASS_RAW_CCSTEPS"))); + bypass_raw_ca = Gtk::manage ( new Gtk::CheckButton (M ("EXPORT_BYPASS_RAW_CA"))); + bypass_raw_df = Gtk::manage ( new Gtk::CheckButton (M ("EXPORT_BYPASS_RAW_DF"))); + bypass_raw_ff = Gtk::manage ( new Gtk::CheckButton (M ("EXPORT_BYPASS_RAW_FF"))); // ---------------------- Bayer sensor frame ----------------------- - Gtk::Frame *bayerFrame = Gtk::manage( new Gtk::Frame(M("TP_RAW_SENSOR_BAYER"))); + Gtk::Frame *bayerFrame = Gtk::manage ( new Gtk::Frame (M ("TP_RAW_SENSOR_BAYER"))); Gtk::VBox* bayerFrameVBox = Gtk::manage (new Gtk::VBox ()); Gtk::HBox* hb_raw_bayer_method = Gtk::manage (new Gtk::HBox ()); - hb_raw_bayer_method->pack_start (*Gtk::manage (new Gtk::Label ( M("EXPORT_RAW_DMETHOD") + ": ")), Gtk::PACK_SHRINK, 4); + hb_raw_bayer_method->pack_start (*Gtk::manage (new Gtk::Label ( M ("EXPORT_RAW_DMETHOD") + ": ")), Gtk::PACK_SHRINK, 4); raw_bayer_method = Gtk::manage (new MyComboBoxText ()); - for( size_t i = 0; i < procparams::RAWParams::BayerSensor::numMethods; i++) { - raw_bayer_method->append(procparams::RAWParams::BayerSensor::methodstring[i]); + for ( size_t i = 0; i < procparams::RAWParams::BayerSensor::numMethods; i++) { + raw_bayer_method->append (procparams::RAWParams::BayerSensor::methodstring[i]); } - raw_bayer_method->set_active(0); + raw_bayer_method->set_active (0); hb_raw_bayer_method->pack_end (*raw_bayer_method, Gtk::PACK_EXPAND_WIDGET, 4); //bypass_raw_all_enhance = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_RAW_ALL_ENHANCE"))); - bypass_raw_bayer_linenoise = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_RAW_LINENOISE"))); - bypass_raw_bayer_greenthresh = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_RAW_GREENTHRESH"))); - bypass_raw_bayer_dcb_iterations = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_RAW_DCB_ITERATIONS"))); - bypass_raw_bayer_dcb_enhance = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_RAW_DCB_ENHANCE"))); - bypass_raw_bayer_lmmse_iterations = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_RAW_LMMSE_ITERATIONS"))); + bypass_raw_bayer_linenoise = Gtk::manage ( new Gtk::CheckButton (M ("EXPORT_BYPASS_RAW_LINENOISE"))); + bypass_raw_bayer_greenthresh = Gtk::manage ( new Gtk::CheckButton (M ("EXPORT_BYPASS_RAW_GREENTHRESH"))); + bypass_raw_bayer_dcb_iterations = Gtk::manage ( new Gtk::CheckButton (M ("EXPORT_BYPASS_RAW_DCB_ITERATIONS"))); + bypass_raw_bayer_dcb_enhance = Gtk::manage ( new Gtk::CheckButton (M ("EXPORT_BYPASS_RAW_DCB_ENHANCE"))); + bypass_raw_bayer_lmmse_iterations = Gtk::manage ( new Gtk::CheckButton (M ("EXPORT_BYPASS_RAW_LMMSE_ITERATIONS"))); // ---------------------- Bayer sensor frame ----------------------- - Gtk::Frame *xtransFrame = Gtk::manage( new Gtk::Frame(M("TP_RAW_SENSOR_XTRANS"))); + Gtk::Frame *xtransFrame = Gtk::manage ( new Gtk::Frame (M ("TP_RAW_SENSOR_XTRANS"))); Gtk::VBox* xtransFrameVBox = Gtk::manage (new Gtk::VBox ()); Gtk::HBox* hb_raw_xtrans_method = Gtk::manage (new Gtk::HBox ()); - hb_raw_xtrans_method->pack_start (*Gtk::manage (new Gtk::Label ( M("EXPORT_RAW_DMETHOD") + ": ")), Gtk::PACK_SHRINK, 4); + hb_raw_xtrans_method->pack_start (*Gtk::manage (new Gtk::Label ( M ("EXPORT_RAW_DMETHOD") + ": ")), Gtk::PACK_SHRINK, 4); raw_xtrans_method = Gtk::manage (new MyComboBoxText ()); - for( size_t i = 0; i < procparams::RAWParams::XTransSensor::numMethods; i++) { - raw_xtrans_method->append(procparams::RAWParams::XTransSensor::methodstring[i]); + for ( size_t i = 0; i < procparams::RAWParams::XTransSensor::numMethods; i++) { + raw_xtrans_method->append (procparams::RAWParams::XTransSensor::methodstring[i]); } - raw_xtrans_method->set_active(0); + raw_xtrans_method->set_active (0); hb_raw_xtrans_method->pack_end (*raw_xtrans_method, Gtk::PACK_EXPAND_WIDGET, 4); // ---------------------------------------------------------------- // start global packing Gtk::HBox* lblbox = Gtk::manage (new Gtk::HBox ()); - lblbox->pack_start (*Gtk::manage (new Gtk::Label (M("EXPORT_PIPELINE"))), Gtk::PACK_SHRINK, 4); + lblbox->pack_start (*Gtk::manage (new Gtk::Label (M ("EXPORT_PIPELINE"))), Gtk::PACK_SHRINK, 4); pack_start (*lblbox, Gtk::PACK_SHRINK, 4); - pack_start(*use_fast_pipeline , Gtk::PACK_SHRINK, 4); - pack_start(*use_normal_pipeline , Gtk::PACK_SHRINK, 4); + pack_start (*use_fast_pipeline, Gtk::PACK_SHRINK, 4); + pack_start (*use_normal_pipeline, Gtk::PACK_SHRINK, 4); - bypass_box->pack_start(*Gtk::manage(new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 4); + bypass_box->pack_start (*Gtk::manage (new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 4); lblbox = Gtk::manage (new Gtk::HBox ()); - lblbox->pack_start (*Gtk::manage (new Gtk::Label (M("EXPORT_BYPASS"))), Gtk::PACK_SHRINK, 4); + lblbox->pack_start (*Gtk::manage (new Gtk::Label (M ("EXPORT_BYPASS"))), Gtk::PACK_SHRINK, 4); bypass_box->pack_start (*lblbox, Gtk::PACK_SHRINK, 4); - bypass_box->pack_start(*bypass_ALL , Gtk::PACK_SHRINK, 4); + bypass_box->pack_start (*bypass_ALL, Gtk::PACK_SHRINK, 4); // bypass_box->pack_start(*Gtk::manage(new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 4); - bypass_box->pack_start(*bypass_sharpening , Gtk::PACK_SHRINK, 4); - bypass_box->pack_start(*bypass_sharpenEdge , Gtk::PACK_SHRINK, 4); - bypass_box->pack_start(*bypass_sharpenMicro , Gtk::PACK_SHRINK, 4); + bypass_box->pack_start (*bypass_sharpening, Gtk::PACK_SHRINK, 4); + bypass_box->pack_start (*bypass_sharpenEdge, Gtk::PACK_SHRINK, 4); + bypass_box->pack_start (*bypass_sharpenMicro, Gtk::PACK_SHRINK, 4); //pack_start(*bypass_lumaDenoise , Gtk::PACK_SHRINK, 4); //pack_start(*bypass_colorDenoise , Gtk::PACK_SHRINK, 4); - bypass_box->pack_start(*bypass_defringe , Gtk::PACK_SHRINK, 4); - bypass_box->pack_start(*bypass_dirpyrDenoise, Gtk::PACK_SHRINK, 4); - bypass_box->pack_start(*bypass_sh_hq , Gtk::PACK_SHRINK, 4); - bypass_box->pack_start(*bypass_dirpyrequalizer , Gtk::PACK_SHRINK, 4); - bypass_box->pack_start(*bypass_wavelet , Gtk::PACK_SHRINK, 4); + bypass_box->pack_start (*bypass_defringe, Gtk::PACK_SHRINK, 4); + bypass_box->pack_start (*bypass_dirpyrDenoise, Gtk::PACK_SHRINK, 4); + bypass_box->pack_start (*bypass_sh_hq, Gtk::PACK_SHRINK, 4); + bypass_box->pack_start (*bypass_dirpyrequalizer, Gtk::PACK_SHRINK, 4); + bypass_box->pack_start (*bypass_wavelet, Gtk::PACK_SHRINK, 4); - bayerFrameVBox->pack_start(*hb_raw_bayer_method, Gtk::PACK_SHRINK, 4); + bayerFrameVBox->pack_start (*hb_raw_bayer_method, Gtk::PACK_SHRINK, 4); //bayerFrameVBox->pack_start(*bypass_raw_all_enhance , Gtk::PACK_SHRINK, 4); - bayerFrameVBox->pack_start(*bypass_raw_bayer_dcb_iterations, Gtk::PACK_SHRINK, 4); - bayerFrameVBox->pack_start(*bypass_raw_bayer_dcb_enhance , Gtk::PACK_SHRINK, 4); - bayerFrameVBox->pack_start(*bypass_raw_bayer_lmmse_iterations, Gtk::PACK_SHRINK, 4); - bayerFrameVBox->pack_start(*bypass_raw_bayer_linenoise , Gtk::PACK_SHRINK, 4); - bayerFrameVBox->pack_start(*bypass_raw_bayer_greenthresh , Gtk::PACK_SHRINK, 4); - bayerFrame->add(*bayerFrameVBox); + bayerFrameVBox->pack_start (*bypass_raw_bayer_dcb_iterations, Gtk::PACK_SHRINK, 4); + bayerFrameVBox->pack_start (*bypass_raw_bayer_dcb_enhance, Gtk::PACK_SHRINK, 4); + bayerFrameVBox->pack_start (*bypass_raw_bayer_lmmse_iterations, Gtk::PACK_SHRINK, 4); + bayerFrameVBox->pack_start (*bypass_raw_bayer_linenoise, Gtk::PACK_SHRINK, 4); + bayerFrameVBox->pack_start (*bypass_raw_bayer_greenthresh, Gtk::PACK_SHRINK, 4); + bayerFrame->add (*bayerFrameVBox); - xtransFrameVBox->pack_start(*hb_raw_xtrans_method, Gtk::PACK_SHRINK, 4); - xtransFrame->add(*xtransFrameVBox); + xtransFrameVBox->pack_start (*hb_raw_xtrans_method, Gtk::PACK_SHRINK, 4); + xtransFrame->add (*xtransFrameVBox); - bypass_box->pack_start(*bypass_raw_ccSteps , Gtk::PACK_SHRINK, 4); - bypass_box->pack_start(*bypass_raw_ca , Gtk::PACK_SHRINK, 4); + bypass_box->pack_start (*bypass_raw_ccSteps, Gtk::PACK_SHRINK, 4); + bypass_box->pack_start (*bypass_raw_ca, Gtk::PACK_SHRINK, 4); - bypass_box->pack_start(*bypass_raw_df , Gtk::PACK_SHRINK, 4); - bypass_box->pack_start(*bypass_raw_ff , Gtk::PACK_SHRINK, 4); + bypass_box->pack_start (*bypass_raw_df, Gtk::PACK_SHRINK, 4); + bypass_box->pack_start (*bypass_raw_ff, Gtk::PACK_SHRINK, 4); - pack_start(*bypass_box, Gtk::PACK_SHRINK); - - pack_start (*Gtk::manage(new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 2); + pack_start (*bypass_box, Gtk::PACK_SHRINK); + + pack_start (*Gtk::manage (new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 2); // Resize options Gtk::HBox* rmbox = Gtk::manage (new Gtk::HBox ()); - rmbox->pack_start (*Gtk::manage (new Gtk::Label (M("TP_RESIZE_LABEL"))), Gtk::PACK_SHRINK, 4); + rmbox->pack_start (*Gtk::manage (new Gtk::Label (M ("TP_RESIZE_LABEL"))), Gtk::PACK_SHRINK, 4); pack_start (*rmbox, Gtk::PACK_SHRINK, 4); Gtk::HBox* wbox = Gtk::manage (new Gtk::HBox ()); Gtk::HBox* hbox = Gtk::manage (new Gtk::HBox ()); MaxWidth = Gtk::manage (new MySpinButton ()); MaxHeight = Gtk::manage (new MySpinButton ()); - wbox->pack_start (*Gtk::manage (new Gtk::Label (M("EXPORT_MAXWIDTH"))), Gtk::PACK_SHRINK, 4); + wbox->pack_start (*Gtk::manage (new Gtk::Label (M ("EXPORT_MAXWIDTH"))), Gtk::PACK_SHRINK, 4); wbox->pack_start (*MaxWidth); - hbox->pack_start (*Gtk::manage (new Gtk::Label (M("EXPORT_MAXHEIGHT"))), Gtk::PACK_SHRINK, 4); + hbox->pack_start (*Gtk::manage (new Gtk::Label (M ("EXPORT_MAXHEIGHT"))), Gtk::PACK_SHRINK, 4); hbox->pack_start (*MaxHeight); pack_start (*wbox, Gtk::PACK_SHRINK, 4); pack_start (*hbox, Gtk::PACK_SHRINK, 4); MaxWidth->set_digits (0); - MaxWidth->set_width_chars(5); - MaxWidth->set_max_width_chars(5); + MaxWidth->set_width_chars (5); + MaxWidth->set_max_width_chars (5); MaxWidth->set_increments (1, 100); MaxWidth->set_value (options.fastexport_resize_width); MaxWidth->set_range (32, 10000); MaxHeight->set_digits (0); - MaxHeight->set_width_chars(5); - MaxHeight->set_max_width_chars(5); + MaxHeight->set_width_chars (5); + MaxHeight->set_max_width_chars (5); MaxHeight->set_increments (1, 100); MaxHeight->set_value (options.fastexport_resize_height); MaxHeight->set_range (32, 10000); // Buttons btnFastExport = Gtk::manage ( new Gtk::Button () ); - btnFastExport->set_tooltip_text(M("EXPORT_PUTTOQUEUEFAST")); + btnFastExport->set_tooltip_text (M ("EXPORT_PUTTOQUEUEFAST")); btnFastExport->set_image (*Gtk::manage (new RTImage ("processing.png"))); - pack_start(*btnFastExport, Gtk::PACK_SHRINK, 4); + pack_start (*btnFastExport, Gtk::PACK_SHRINK, 4); // add panel ending Gtk::VBox* vboxpe = Gtk::manage (new Gtk::VBox ()); Gtk::HSeparator* hseptpe = Gtk::manage (new Gtk::HSeparator ()); - Gtk::Image* peImg = Gtk::manage (new RTImage("PanelEnding.png")); - vboxpe->pack_start(*hseptpe, Gtk::PACK_SHRINK, 4); - vboxpe->pack_start(*peImg); - pack_start(*vboxpe, Gtk::PACK_SHRINK, 0); + Gtk::Image* peImg = Gtk::manage (new RTImage ("PanelEnding.png")); + vboxpe->pack_start (*hseptpe, Gtk::PACK_SHRINK, 4); + vboxpe->pack_start (*peImg); + pack_start (*vboxpe, Gtk::PACK_SHRINK, 0); - use_fast_pipeline->signal_toggled().connect(sigc::mem_fun(*this, &ExportPanel::use_fast_pipeline_toggled)); - btnFastExport->signal_clicked().connect( sigc::mem_fun(*this, &ExportPanel::FastExportPressed) ); + use_fast_pipeline->signal_toggled().connect (sigc::mem_fun (*this, &ExportPanel::use_fast_pipeline_toggled)); + btnFastExport->signal_clicked().connect ( sigc::mem_fun (*this, &ExportPanel::FastExportPressed) ); //btnExportLoadSettings->signal_clicked().connect( sigc::mem_fun(*this, &ExportPanel::LoadSettings) ); //btnExportSaveSettings->signal_clicked().connect( sigc::mem_fun(*this, &ExportPanel::SaveSettings) ); - bypass_ALLconn = bypass_ALL->signal_toggled().connect (sigc::mem_fun(*this, &ExportPanel::bypassALL_Toggled)); + bypass_ALLconn = bypass_ALL->signal_toggled().connect (sigc::mem_fun (*this, &ExportPanel::bypassALL_Toggled)); - bypass_sharpeningConn = bypass_sharpening->signal_toggled().connect (sigc::bind (sigc::mem_fun(*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); - bypass_sharpenEdgeConn = bypass_sharpenEdge->signal_toggled().connect (sigc::bind (sigc::mem_fun(*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); - bypass_sharpenMicroConn = bypass_sharpenMicro->signal_toggled().connect (sigc::bind (sigc::mem_fun(*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); + bypass_sharpeningConn = bypass_sharpening->signal_toggled().connect (sigc::bind (sigc::mem_fun (*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); + bypass_sharpenEdgeConn = bypass_sharpenEdge->signal_toggled().connect (sigc::bind (sigc::mem_fun (*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); + bypass_sharpenMicroConn = bypass_sharpenMicro->signal_toggled().connect (sigc::bind (sigc::mem_fun (*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); //bypass_lumaDenoiseConn = bypass_lumaDenoise->signal_toggled().connect (sigc::bind (sigc::mem_fun(*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); //bypass_colorDenoiseConn = bypass_colorDenoise->signal_toggled().connect (sigc::bind (sigc::mem_fun(*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); - bypass_defringeConn = bypass_defringe->signal_toggled().connect (sigc::bind (sigc::mem_fun(*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); - bypass_dirpyrDenoiseConn = bypass_dirpyrDenoise->signal_toggled().connect (sigc::bind (sigc::mem_fun(*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); - bypass_sh_hqConn = bypass_sh_hq->signal_toggled().connect (sigc::bind (sigc::mem_fun(*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); - bypass_dirpyrequalizerConn = bypass_dirpyrequalizer->signal_toggled().connect (sigc::bind (sigc::mem_fun(*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); - bypass_waveletConn = bypass_wavelet->signal_toggled().connect (sigc::bind (sigc::mem_fun(*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); + bypass_defringeConn = bypass_defringe->signal_toggled().connect (sigc::bind (sigc::mem_fun (*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); + bypass_dirpyrDenoiseConn = bypass_dirpyrDenoise->signal_toggled().connect (sigc::bind (sigc::mem_fun (*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); + bypass_sh_hqConn = bypass_sh_hq->signal_toggled().connect (sigc::bind (sigc::mem_fun (*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); + bypass_dirpyrequalizerConn = bypass_dirpyrequalizer->signal_toggled().connect (sigc::bind (sigc::mem_fun (*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); + bypass_waveletConn = bypass_wavelet->signal_toggled().connect (sigc::bind (sigc::mem_fun (*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); //bypass_raw_all_enhanceConn = bypass_raw_bayer_all_enhance->signal_toggled().connect (sigc::bind (sigc::mem_fun(*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); - bypass_raw_bayer_dcb_iterationsConn = bypass_raw_bayer_dcb_iterations->signal_toggled().connect (sigc::bind (sigc::mem_fun(*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); - bypass_raw_bayer_dcb_enhanceConn = bypass_raw_bayer_dcb_enhance->signal_toggled().connect (sigc::bind (sigc::mem_fun(*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); - bypass_raw_bayer_lmmse_iterationsConn = bypass_raw_bayer_lmmse_iterations->signal_toggled().connect (sigc::bind (sigc::mem_fun(*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); - bypass_raw_bayer_linenoiseConn = bypass_raw_bayer_linenoise->signal_toggled().connect (sigc::bind (sigc::mem_fun(*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); - bypass_raw_bayer_greenthreshConn = bypass_raw_bayer_greenthresh->signal_toggled().connect (sigc::bind (sigc::mem_fun(*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); - bypass_raw_ccStepsConn = bypass_raw_ccSteps->signal_toggled().connect (sigc::bind (sigc::mem_fun(*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); - bypass_raw_caConn = bypass_raw_ca->signal_toggled().connect (sigc::bind (sigc::mem_fun(*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); - bypass_raw_dfConn = bypass_raw_df->signal_toggled().connect (sigc::bind (sigc::mem_fun(*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); - bypass_raw_ffConn = bypass_raw_ff->signal_toggled().connect (sigc::bind (sigc::mem_fun(*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); + bypass_raw_bayer_dcb_iterationsConn = bypass_raw_bayer_dcb_iterations->signal_toggled().connect (sigc::bind (sigc::mem_fun (*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); + bypass_raw_bayer_dcb_enhanceConn = bypass_raw_bayer_dcb_enhance->signal_toggled().connect (sigc::bind (sigc::mem_fun (*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); + bypass_raw_bayer_lmmse_iterationsConn = bypass_raw_bayer_lmmse_iterations->signal_toggled().connect (sigc::bind (sigc::mem_fun (*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); + bypass_raw_bayer_linenoiseConn = bypass_raw_bayer_linenoise->signal_toggled().connect (sigc::bind (sigc::mem_fun (*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); + bypass_raw_bayer_greenthreshConn = bypass_raw_bayer_greenthresh->signal_toggled().connect (sigc::bind (sigc::mem_fun (*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); + bypass_raw_ccStepsConn = bypass_raw_ccSteps->signal_toggled().connect (sigc::bind (sigc::mem_fun (*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); + bypass_raw_caConn = bypass_raw_ca->signal_toggled().connect (sigc::bind (sigc::mem_fun (*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); + bypass_raw_dfConn = bypass_raw_df->signal_toggled().connect (sigc::bind (sigc::mem_fun (*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); + bypass_raw_ffConn = bypass_raw_ff->signal_toggled().connect (sigc::bind (sigc::mem_fun (*bypass_ALL, &Gtk::CheckButton::set_inconsistent), true)); LoadDefaultSettings(); } @@ -251,39 +251,39 @@ void ExportPanel::SaveSettingsAsDefault() } \ } while (false) // Save fast export settings to options - FE_OPT_STORE_(options.fastexport_bypass_sharpening, bypass_sharpening->get_active ()); - FE_OPT_STORE_(options.fastexport_bypass_sharpenEdge, bypass_sharpenEdge->get_active ()); - FE_OPT_STORE_(options.fastexport_bypass_sharpenMicro, bypass_sharpenMicro->get_active ()); + FE_OPT_STORE_ (options.fastexport_bypass_sharpening, bypass_sharpening->get_active ()); + FE_OPT_STORE_ (options.fastexport_bypass_sharpenEdge, bypass_sharpenEdge->get_active ()); + FE_OPT_STORE_ (options.fastexport_bypass_sharpenMicro, bypass_sharpenMicro->get_active ()); //options.fastexport_bypass_lumaDenoise = bypass_lumaDenoise->get_active (); //options.fastexport_bypass_colorDenoise = bypass_colorDenoise->get_active (); - FE_OPT_STORE_(options.fastexport_bypass_defringe, bypass_defringe->get_active ()); - FE_OPT_STORE_(options.fastexport_bypass_dirpyrDenoise, bypass_dirpyrDenoise->get_active ()); - FE_OPT_STORE_(options.fastexport_bypass_sh_hq, bypass_sh_hq->get_active ()); - FE_OPT_STORE_(options.fastexport_bypass_dirpyrequalizer, bypass_dirpyrequalizer->get_active ()); - FE_OPT_STORE_(options.fastexport_bypass_wavelet, bypass_wavelet->get_active ()); + FE_OPT_STORE_ (options.fastexport_bypass_defringe, bypass_defringe->get_active ()); + FE_OPT_STORE_ (options.fastexport_bypass_dirpyrDenoise, bypass_dirpyrDenoise->get_active ()); + FE_OPT_STORE_ (options.fastexport_bypass_sh_hq, bypass_sh_hq->get_active ()); + FE_OPT_STORE_ (options.fastexport_bypass_dirpyrequalizer, bypass_dirpyrequalizer->get_active ()); + FE_OPT_STORE_ (options.fastexport_bypass_wavelet, bypass_wavelet->get_active ()); //options.fastexport_bypass_raw_bayer_all_enhance = bypass_raw_all_enhance->get_active (); - FE_OPT_STORE_(options.fastexport_bypass_raw_bayer_dcb_iterations, bypass_raw_bayer_dcb_iterations->get_active ()); - FE_OPT_STORE_(options.fastexport_bypass_raw_bayer_dcb_enhance, bypass_raw_bayer_dcb_enhance->get_active ()); - FE_OPT_STORE_(options.fastexport_bypass_raw_bayer_lmmse_iterations, bypass_raw_bayer_lmmse_iterations->get_active()); - FE_OPT_STORE_(options.fastexport_bypass_raw_bayer_linenoise, bypass_raw_bayer_linenoise->get_active ()); - FE_OPT_STORE_(options.fastexport_bypass_raw_bayer_greenthresh, bypass_raw_bayer_greenthresh->get_active ()); - FE_OPT_STORE_(options.fastexport_bypass_raw_ccSteps, bypass_raw_ccSteps->get_active ()); - FE_OPT_STORE_(options.fastexport_bypass_raw_ca, bypass_raw_ca->get_active ()); - FE_OPT_STORE_(options.fastexport_bypass_raw_df, bypass_raw_df->get_active ()); - FE_OPT_STORE_(options.fastexport_bypass_raw_ff, bypass_raw_ff->get_active ()); + FE_OPT_STORE_ (options.fastexport_bypass_raw_bayer_dcb_iterations, bypass_raw_bayer_dcb_iterations->get_active ()); + FE_OPT_STORE_ (options.fastexport_bypass_raw_bayer_dcb_enhance, bypass_raw_bayer_dcb_enhance->get_active ()); + FE_OPT_STORE_ (options.fastexport_bypass_raw_bayer_lmmse_iterations, bypass_raw_bayer_lmmse_iterations->get_active()); + FE_OPT_STORE_ (options.fastexport_bypass_raw_bayer_linenoise, bypass_raw_bayer_linenoise->get_active ()); + FE_OPT_STORE_ (options.fastexport_bypass_raw_bayer_greenthresh, bypass_raw_bayer_greenthresh->get_active ()); + FE_OPT_STORE_ (options.fastexport_bypass_raw_ccSteps, bypass_raw_ccSteps->get_active ()); + FE_OPT_STORE_ (options.fastexport_bypass_raw_ca, bypass_raw_ca->get_active ()); + FE_OPT_STORE_ (options.fastexport_bypass_raw_df, bypass_raw_df->get_active ()); + FE_OPT_STORE_ (options.fastexport_bypass_raw_ff, bypass_raw_ff->get_active ()); //saving Bayer demosaic_method int currentRow = raw_bayer_method->get_active_row_number(); - if( currentRow >= 0 && currentRow < procparams::RAWParams::BayerSensor::numMethods) { - FE_OPT_STORE_(options.fastexport_raw_bayer_method, procparams::RAWParams::BayerSensor::methodstring[currentRow]); + if ( currentRow >= 0 && currentRow < procparams::RAWParams::BayerSensor::numMethods) { + FE_OPT_STORE_ (options.fastexport_raw_bayer_method, procparams::RAWParams::BayerSensor::methodstring[currentRow]); } //saving X-Trans demosaic_method currentRow = raw_xtrans_method->get_active_row_number(); - if( currentRow >= 0 && currentRow < procparams::RAWParams::XTransSensor::numMethods) { - FE_OPT_STORE_(options.fastexport_raw_xtrans_method, procparams::RAWParams::XTransSensor::methodstring[currentRow]); + if ( currentRow >= 0 && currentRow < procparams::RAWParams::XTransSensor::numMethods) { + FE_OPT_STORE_ (options.fastexport_raw_xtrans_method, procparams::RAWParams::XTransSensor::methodstring[currentRow]); } // options.fastexport_icm_input = icm_input ; @@ -295,15 +295,20 @@ void ExportPanel::SaveSettingsAsDefault() // options.fastexport_resize_appliesTo = resize_appliesTo; // options.fastexport_resize_dataspec = resize_dataspec ; - FE_OPT_STORE_(options.fastexport_resize_method, "Lanczos"); - FE_OPT_STORE_(options.fastexport_resize_width, MaxWidth->get_value_as_int ()); - FE_OPT_STORE_(options.fastexport_resize_height, MaxHeight->get_value_as_int ()); + FE_OPT_STORE_ (options.fastexport_resize_method, "Lanczos"); + FE_OPT_STORE_ (options.fastexport_resize_width, MaxWidth->get_value_as_int ()); + FE_OPT_STORE_ (options.fastexport_resize_height, MaxHeight->get_value_as_int ()); - FE_OPT_STORE_(options.fastexport_use_fast_pipeline, use_fast_pipeline->get_active()); + FE_OPT_STORE_ (options.fastexport_use_fast_pipeline, use_fast_pipeline->get_active()); #undef FE_OPT_STORE_ if (changed) { - Options::save(); + try { + Options::save(); + } catch (Options::Error &e) { + Gtk::MessageDialog msgd (getToplevelWindow (this), e.get_msg(), true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_CLOSE, true); + msgd.run(); + } } } @@ -323,7 +328,7 @@ void ExportPanel::LoadDefaultSettings() //bypass_raw_bayer_all_enhance->set_active (options.fastexport_bypass_raw_bayer_all_enhance ); bypass_raw_bayer_dcb_iterations->set_active (options.fastexport_bypass_raw_bayer_dcb_iterations ); bypass_raw_bayer_dcb_enhance->set_active (options.fastexport_bypass_raw_bayer_dcb_enhance ); - bypass_raw_bayer_lmmse_iterations->set_active(options.fastexport_bypass_raw_bayer_lmmse_iterations); + bypass_raw_bayer_lmmse_iterations->set_active (options.fastexport_bypass_raw_bayer_lmmse_iterations); bypass_raw_bayer_linenoise->set_active (options.fastexport_bypass_raw_bayer_linenoise ); bypass_raw_bayer_greenthresh->set_active (options.fastexport_bypass_raw_bayer_greenthresh ); bypass_raw_ccSteps->set_active (options.fastexport_bypass_raw_ccSteps ); @@ -332,20 +337,20 @@ void ExportPanel::LoadDefaultSettings() bypass_raw_ff->set_active (options.fastexport_bypass_raw_ff ); // Bayer demosaic method - raw_bayer_method->set_active(procparams::RAWParams::BayerSensor::numMethods); + raw_bayer_method->set_active (procparams::RAWParams::BayerSensor::numMethods); - for( size_t i = 0; i < procparams::RAWParams::BayerSensor::numMethods; i++) - if( options.fastexport_raw_bayer_method == procparams::RAWParams::BayerSensor::methodstring[i]) { - raw_bayer_method->set_active(i); + for ( size_t i = 0; i < procparams::RAWParams::BayerSensor::numMethods; i++) + if ( options.fastexport_raw_bayer_method == procparams::RAWParams::BayerSensor::methodstring[i]) { + raw_bayer_method->set_active (i); break; } // X-Trans demosaic method - raw_xtrans_method->set_active(procparams::RAWParams::XTransSensor::numMethods); + raw_xtrans_method->set_active (procparams::RAWParams::XTransSensor::numMethods); - for( size_t i = 0; i < procparams::RAWParams::XTransSensor::numMethods; i++) - if( options.fastexport_raw_xtrans_method == procparams::RAWParams::XTransSensor::methodstring[i]) { - raw_xtrans_method->set_active(i); + for ( size_t i = 0; i < procparams::RAWParams::XTransSensor::numMethods; i++) + if ( options.fastexport_raw_xtrans_method == procparams::RAWParams::XTransSensor::methodstring[i]) { + raw_xtrans_method->set_active (i); break; } @@ -358,14 +363,14 @@ void ExportPanel::LoadDefaultSettings() // resize_appliesTo = options.fastexport_resize_appliesTo; // resize_dataspec = options.fastexport_resize_dataspec ; - MaxWidth->set_value(options.fastexport_resize_width); - MaxHeight->set_value(options.fastexport_resize_height); + MaxWidth->set_value (options.fastexport_resize_width); + MaxHeight->set_value (options.fastexport_resize_height); if (options.fastexport_use_fast_pipeline) { - use_fast_pipeline->set_active(true); - bypass_box->set_sensitive(false); + use_fast_pipeline->set_active (true); + bypass_box->set_sensitive (false); } else { - use_normal_pipeline->set_active(true); + use_normal_pipeline->set_active (true); } } @@ -405,26 +410,26 @@ void ExportPanel::bypassALL_Toggled() bypass_ALL->set_inconsistent (false); - bypass_sharpening->set_active(bypass_ALL->get_active()); - bypass_sharpenEdge->set_active(bypass_ALL->get_active()); - bypass_sharpenMicro->set_active(bypass_ALL->get_active()); + bypass_sharpening->set_active (bypass_ALL->get_active()); + bypass_sharpenEdge->set_active (bypass_ALL->get_active()); + bypass_sharpenMicro->set_active (bypass_ALL->get_active()); //bypass_lumaDenoise->set_active(bypass_ALL->get_active()); //bypass_colorDenoise->set_active(bypass_ALL->get_active()); - bypass_defringe->set_active(bypass_ALL->get_active()); - bypass_dirpyrDenoise->set_active(bypass_ALL->get_active()); - bypass_sh_hq->set_active(bypass_ALL->get_active()); - bypass_dirpyrequalizer->set_active(bypass_ALL->get_active()); - bypass_wavelet->set_active(bypass_ALL->get_active()); + bypass_defringe->set_active (bypass_ALL->get_active()); + bypass_dirpyrDenoise->set_active (bypass_ALL->get_active()); + bypass_sh_hq->set_active (bypass_ALL->get_active()); + bypass_dirpyrequalizer->set_active (bypass_ALL->get_active()); + bypass_wavelet->set_active (bypass_ALL->get_active()); //bypass_raw_bayer_all_enhance->set_active(bypass_ALL->get_active()); - bypass_raw_bayer_dcb_iterations->set_active(bypass_ALL->get_active()); - bypass_raw_bayer_dcb_enhance->set_active(bypass_ALL->get_active()); - bypass_raw_bayer_lmmse_iterations->set_active(bypass_ALL->get_active()); - bypass_raw_bayer_linenoise->set_active(bypass_ALL->get_active()); - bypass_raw_bayer_greenthresh->set_active(bypass_ALL->get_active()); - bypass_raw_ccSteps->set_active(bypass_ALL->get_active()); - bypass_raw_ca->set_active(bypass_ALL->get_active()); - bypass_raw_df->set_active(bypass_ALL->get_active()); - bypass_raw_ff->set_active(bypass_ALL->get_active()); + bypass_raw_bayer_dcb_iterations->set_active (bypass_ALL->get_active()); + bypass_raw_bayer_dcb_enhance->set_active (bypass_ALL->get_active()); + bypass_raw_bayer_lmmse_iterations->set_active (bypass_ALL->get_active()); + bypass_raw_bayer_linenoise->set_active (bypass_ALL->get_active()); + bypass_raw_bayer_greenthresh->set_active (bypass_ALL->get_active()); + bypass_raw_ccSteps->set_active (bypass_ALL->get_active()); + bypass_raw_ca->set_active (bypass_ALL->get_active()); + bypass_raw_df->set_active (bypass_ALL->get_active()); + bypass_raw_ff->set_active (bypass_ALL->get_active()); bypass_sharpeningConn.block (false); bypass_sharpenEdgeConn.block (false); @@ -450,7 +455,7 @@ void ExportPanel::bypassALL_Toggled() void ExportPanel::use_fast_pipeline_toggled() { - bypass_box->set_sensitive(!use_fast_pipeline->get_active()); + bypass_box->set_sensitive (!use_fast_pipeline->get_active()); } /* diff --git a/rtgui/fattaltonemap.cc b/rtgui/fattaltonemap.cc new file mode 100644 index 000000000..10dba51cf --- /dev/null +++ b/rtgui/fattaltonemap.cc @@ -0,0 +1,126 @@ +/** -*- C++ -*- + * + * This file is part of RawTherapee. + * + * Copyright (c) 2017 Alberto Griggio + * + * 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 "fattaltonemap.h" +#include +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +FattalToneMapping::FattalToneMapping(): FoldableToolPanel(this, "fattal", M("TP_TM_FATTAL_LABEL"), true, true) +{ + +// setEnabledTooltipMarkup(M("TP_EPD_TOOLTIP")); + + amount = Gtk::manage(new Adjuster (M("TP_TM_FATTAL_AMOUNT"), 1., 100., 1., 0.0)); + threshold = Gtk::manage(new Adjuster (M("TP_TM_FATTAL_THRESHOLD"), -100., 100., 1., 0.0)); + + amount->setAdjusterListener(this); + threshold->setAdjusterListener(this); + + amount->show(); + threshold->show(); + + pack_start(*amount); + pack_start(*threshold); +} + +void FattalToneMapping::read(const ProcParams *pp, const ParamsEdited *pedited) +{ + disableListener(); + + if(pedited) { + threshold->setEditedState(pedited->fattal.threshold ? Edited : UnEdited); + amount->setEditedState(pedited->fattal.amount ? Edited : UnEdited); + set_inconsistent(multiImage && !pedited->fattal.enabled); + } + + setEnabled(pp->fattal.enabled); + threshold->setValue(pp->fattal.threshold); + amount->setValue(pp->fattal.amount); + + enableListener(); +} + +void FattalToneMapping::write(ProcParams *pp, ParamsEdited *pedited) +{ + pp->fattal.threshold = threshold->getValue(); + pp->fattal.amount = amount->getValue(); + pp->fattal.enabled = getEnabled(); + + if(pedited) { + pedited->fattal.threshold = threshold->getEditedState(); + pedited->fattal.amount = amount->getEditedState(); + pedited->fattal.enabled = !get_inconsistent(); + } +} + +void FattalToneMapping::setDefaults(const ProcParams *defParams, const ParamsEdited *pedited) +{ + threshold->setDefault(defParams->fattal.threshold); + amount->setDefault(defParams->fattal.amount); + + if(pedited) { + threshold->setDefaultEditedState(pedited->fattal.threshold ? Edited : UnEdited); + amount->setDefaultEditedState(pedited->fattal.amount ? Edited : UnEdited); + } else { + threshold->setDefaultEditedState(Irrelevant); + amount->setDefaultEditedState(Irrelevant); + } +} + +void FattalToneMapping::adjusterChanged(Adjuster* a, double newval) +{ + if(listener && getEnabled()) { + if(a == threshold) { + listener->panelChanged(EvTMFattalThreshold, a->getTextValue()); + } else if(a == amount) { + listener->panelChanged(EvTMFattalAmount, a->getTextValue()); + } + } +} + +void FattalToneMapping::enabledChanged () +{ + if (listener) { + if (get_inconsistent()) { + listener->panelChanged (EvTMFattalEnabled, M("GENERAL_UNCHANGED")); + } else if (getEnabled()) { + listener->panelChanged (EvTMFattalEnabled, M("GENERAL_ENABLED")); + } else { + listener->panelChanged (EvTMFattalEnabled, M("GENERAL_DISABLED")); + } + } +} + +void FattalToneMapping::setBatchMode(bool batchMode) +{ + ToolPanel::setBatchMode(batchMode); + + threshold->showEditedCB(); + amount->showEditedCB(); +} + +void FattalToneMapping::setAdjusterBehavior (bool alphaAdd, bool betaAdd) +{ + threshold->setAddMode(alphaAdd); + amount->setAddMode(betaAdd); +} + diff --git a/rtgui/fattaltonemap.h b/rtgui/fattaltonemap.h new file mode 100644 index 000000000..2398970ce --- /dev/null +++ b/rtgui/fattaltonemap.h @@ -0,0 +1,46 @@ +/** -*- C++ -*- + * + * This file is part of RawTherapee. + * + * Copyright (c) 2017 Alberto Griggio + * + * 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 . + */ +#pragma once + +#include +#include "adjuster.h" +#include "toolpanel.h" + +class FattalToneMapping: public ToolParamBlock, public AdjusterListener, public FoldableToolPanel +{ +protected: + Adjuster *threshold; + Adjuster *amount; + +public: + + FattalToneMapping(); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr); + void setBatchMode (bool batchMode); + + void adjusterChanged (Adjuster* a, double newval); + void enabledChanged (); + void setAdjusterBehavior (bool alphaAdd, bool betaAdd); + +}; + diff --git a/rtgui/filebrowser.cc b/rtgui/filebrowser.cc index 10d4809ed..cda737285 100644 --- a/rtgui/filebrowser.cc +++ b/rtgui/filebrowser.cc @@ -401,6 +401,8 @@ FileBrowser::FileBrowser () : copyprof->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_C, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE); pasteprof->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_V, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE); partpasteprof->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_V, Gdk::CONTROL_MASK | Gdk::SHIFT_MASK, Gtk::ACCEL_VISIBLE); + copyTo->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_C, Gdk::CONTROL_MASK | Gdk::SHIFT_MASK, Gtk::ACCEL_VISIBLE); + moveTo->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_M, Gdk::CONTROL_MASK | Gdk::SHIFT_MASK, Gtk::ACCEL_VISIBLE); // Bind to event handlers open->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), open)); @@ -440,8 +442,6 @@ FileBrowser::FileBrowser () : clearprof->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), clearprof)); cachemenu->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), cachemenu)); - - // A separate pop-up menu for Color Labels int c = 0; pmenuColorLabels = new Gtk::Menu (); @@ -497,6 +497,8 @@ void FileBrowser::rightClicked (ThumbBrowserEntryBase* entry) partpasteprof->set_sensitive (clipboard.hasProcParams()); copyprof->set_sensitive (selected.size() == 1); clearprof->set_sensitive (!selected.empty()); + copyTo->set_sensitive (!selected.empty()); + moveTo->set_sensitive (!selected.empty()); } // submenuDF @@ -975,15 +977,11 @@ void FileBrowser::menuItemActivated (Gtk::MenuItem* m) bppcl->endBatchPParamsChange(); } } else if (m == clearFromCache) { - for (size_t i = 0; i < mselected.size(); i++) { - tbl->clearFromCacheRequested (mselected, false); - } + tbl->clearFromCacheRequested (mselected, false); //queue_draw (); } else if (m == clearFromCacheFull) { - for (size_t i = 0; i < mselected.size(); i++) { - tbl->clearFromCacheRequested (mselected, true); - } + tbl->clearFromCacheRequested (mselected, true); //queue_draw (); } else if (miOpenDefaultViewer != nullptr && m == miOpenDefaultViewer) { @@ -1119,7 +1117,14 @@ bool FileBrowser::keyPressed (GdkEventKey* event) #ifdef __WIN32__ bool altgr = event->state & GDK_MOD2_MASK; #endif - if ((event->keyval == GDK_KEY_C || event->keyval == GDK_KEY_c || event->keyval == GDK_KEY_Insert) && ctrl) { + + if ((event->keyval == GDK_KEY_C || event->keyval == GDK_KEY_c) && ctrl && shift) { + menuItemActivated (copyTo); + return true; + } else if ((event->keyval == GDK_KEY_M || event->keyval == GDK_KEY_m) && ctrl && shift) { + menuItemActivated (moveTo); + return true; + } else if ((event->keyval == GDK_KEY_C || event->keyval == GDK_KEY_c || event->keyval == GDK_KEY_Insert) && ctrl) { copyProfile (); return true; } else if ((event->keyval == GDK_KEY_V || event->keyval == GDK_KEY_v) && ctrl && !shift) { @@ -1539,8 +1544,8 @@ bool FileBrowser::checkFilter (ThumbBrowserEntryBase* entryb) // true -> entry && (!filter.exifFilter.filterExpComp || filter.exifFilter.expcomp.count(cfs->expcomp) > 0); return - (!filter.exifFilter.filterShutter || (rtengine::ImageMetaData::shutterFromString(rtengine::ImageMetaData::shutterToString(cfs->shutter)) >= filter.exifFilter.shutterFrom - tol2 && rtengine::ImageMetaData::shutterFromString(rtengine::ImageMetaData::shutterToString(cfs->shutter)) <= filter.exifFilter.shutterTo + tol2)) - && (!filter.exifFilter.filterFNumber || (rtengine::ImageMetaData::apertureFromString(rtengine::ImageMetaData::apertureToString(cfs->fnumber)) >= filter.exifFilter.fnumberFrom - tol2 && rtengine::ImageMetaData::apertureFromString(rtengine::ImageMetaData::apertureToString(cfs->fnumber)) <= filter.exifFilter.fnumberTo + tol2)) + (!filter.exifFilter.filterShutter || (rtengine::FramesMetaData::shutterFromString(rtengine::FramesMetaData::shutterToString(cfs->shutter)) >= filter.exifFilter.shutterFrom - tol2 && rtengine::FramesMetaData::shutterFromString(rtengine::FramesMetaData::shutterToString(cfs->shutter)) <= filter.exifFilter.shutterTo + tol2)) + && (!filter.exifFilter.filterFNumber || (rtengine::FramesMetaData::apertureFromString(rtengine::FramesMetaData::apertureToString(cfs->fnumber)) >= filter.exifFilter.fnumberFrom - tol2 && rtengine::FramesMetaData::apertureFromString(rtengine::FramesMetaData::apertureToString(cfs->fnumber)) <= filter.exifFilter.fnumberTo + tol2)) && (!filter.exifFilter.filterFocalLen || (cfs->focalLen >= filter.exifFilter.focalFrom - tol && cfs->focalLen <= filter.exifFilter.focalTo + tol)) && (!filter.exifFilter.filterISO || (cfs->iso >= filter.exifFilter.isoFrom && cfs->iso <= filter.exifFilter.isoTo)) && (!filter.exifFilter.filterExpComp || filter.exifFilter.expcomp.count(cfs->expcomp) > 0) diff --git a/rtgui/filebrowserentry.cc b/rtgui/filebrowserentry.cc index d76870788..c3adae3aa 100644 --- a/rtgui/filebrowserentry.cc +++ b/rtgui/filebrowserentry.cc @@ -36,6 +36,8 @@ bool FileBrowserEntry::iconsLoaded(false); Glib::RefPtr FileBrowserEntry::editedIcon; Glib::RefPtr FileBrowserEntry::recentlySavedIcon; Glib::RefPtr FileBrowserEntry::enqueuedIcon; +Glib::RefPtr FileBrowserEntry::hdr; +Glib::RefPtr FileBrowserEntry::ps; FileBrowserEntry::FileBrowserEntry (Thumbnail* thm, const Glib::ustring& fname) : ThumbBrowserEntryBase (fname), wasInside(false), iatlistener(nullptr), press_x(0), press_y(0), action_x(0), action_y(0), rot_deg(0.0), landscape(true), cropgl(nullptr), state(SNormal), crop_custom_ratio(0.f) @@ -57,6 +59,8 @@ FileBrowserEntry::FileBrowserEntry (Thumbnail* thm, const Glib::ustring& fname) editedIcon = RTImage::createFromFile ("edited.png"); recentlySavedIcon = RTImage::createFromFile ("recent-save.png"); enqueuedIcon = RTImage::createFromFile ("processing.png"); + hdr = RTImage::createFromFile ("HDR-thumbnail.png"); + ps = RTImage::createFromFile ("PixelShift-thumbnail.png"); iconsLoaded = true; } @@ -137,6 +141,26 @@ std::vector > FileBrowserEntry::getIconsOnImageArea () return ret; } +std::vector > FileBrowserEntry::getSpecificityIconsOnImageArea () +{ + + std::vector > ret; + + if (!thumbnail) { + return ret; + } + + if (thumbnail->isHDR() && hdr) { + ret.push_back (hdr); + } + + if (thumbnail->isPixelShift() && ps) { + ret.push_back (ps); + } + + return ret; +} + void FileBrowserEntry::customBackBufferUpdate (Cairo::RefPtr c) { if(scale != 1.0 && cropParams.enabled) { // somewhere in pipeline customBackBufferUpdate is called when scale == 1.0, which is nonsense for a thumb diff --git a/rtgui/filebrowserentry.h b/rtgui/filebrowserentry.h index 4c3d519ab..423128ddb 100644 --- a/rtgui/filebrowserentry.h +++ b/rtgui/filebrowserentry.h @@ -70,6 +70,8 @@ public: static Glib::RefPtr editedIcon; static Glib::RefPtr recentlySavedIcon; static Glib::RefPtr enqueuedIcon; + static Glib::RefPtr hdr; + static Glib::RefPtr ps; FileBrowserEntry (Thumbnail* thm, const Glib::ustring& fname); ~FileBrowserEntry (); @@ -87,6 +89,7 @@ public: void calcThumbnailSize (); virtual std::vector > getIconsOnImageArea (); + virtual std::vector > getSpecificityIconsOnImageArea (); virtual void getIconSize (int& w, int& h); // thumbnaillistener interface diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index eafe32fcd..a2088b9e2 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -770,6 +770,8 @@ void FileCatalog::previewReady (int dir_id, FileBrowserEntry* fdn) if (cfs->focalLen > dirEFS.focalTo) { dirEFS.focalTo = cfs->focalLen; } + + //TODO: ass filters for HDR and PixelShift files } dirEFS.filetypes.insert (cfs->filetype); diff --git a/rtgui/filmsimulation.cc b/rtgui/filmsimulation.cc index a1471f970..89ab31748 100644 --- a/rtgui/filmsimulation.cc +++ b/rtgui/filmsimulation.cc @@ -1,3 +1,6 @@ +#include +#include + #include "filmsimulation.h" #include @@ -56,13 +59,11 @@ bool notifySlowParseDir (const std::chrono::system_clock::time_point& startedAt) } -typedef std::vector Strings; - FilmSimulation::FilmSimulation() : FoldableToolPanel( this, "filmsimulation", M("TP_FILMSIMULATION_LABEL"), false, true ) { - m_clutComboBox = Gtk::manage( new ClutComboBox() ); - int foundClutsCount = m_clutComboBox->fillFromDir( options.clutsDir ); + m_clutComboBox = Gtk::manage( new ClutComboBox(options.clutsDir) ); + int foundClutsCount = m_clutComboBox->foundClutsCount(); if ( foundClutsCount == 0 ) { pack_start( *Gtk::manage( new Gtk::Label( M("TP_FILMSIMULATION_ZEROCLUTSFOUND") ) ) ); @@ -116,7 +117,7 @@ void FilmSimulation::adjusterChanged( Adjuster* a, double newval ) void FilmSimulation::setBatchMode( bool batchMode ) { ToolPanel::setBatchMode( batchMode ); - m_clutComboBox->addUnchangedEntry(); + m_clutComboBox->setBatchMode(batchMode); } void FilmSimulation::read( const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited ) @@ -196,33 +197,121 @@ void FilmSimulation::trimValues( rtengine::procparams::ProcParams* pp ) //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +std::unique_ptr ClutComboBox::cm; +std::unique_ptr ClutComboBox::cm2; + +ClutComboBox::ClutComboBox(const Glib::ustring &path): + MyComboBox(), + batchMode(false) +{ + if (!cm) { + cm.reset(new ClutModel(path)); + } + if (!cm2 && options.multiDisplayMode) { + cm2.reset(new ClutModel(path)); + } + + set_model(m_model()); + + if (cm->count > 0) { + pack_start(m_columns().label, false); + } + + if (!options.multiDisplayMode) { + signal_map().connect(sigc::mem_fun(*this, &ClutComboBox::updateUnchangedEntry)); + } +} + + +inline Glib::RefPtr &ClutComboBox::m_model() +{ + if (!batchMode || !options.multiDisplayMode) { + return cm->m_model; + } else { + return cm2->m_model; + } +} + + +inline ClutComboBox::ClutColumns &ClutComboBox::m_columns() +{ + if (!batchMode || !options.multiDisplayMode) { + return cm->m_columns; + } else { + return cm2->m_columns; + } +} + + +void ClutComboBox::setBatchMode(bool yes) +{ + if (batchMode != yes) { + batchMode = yes; + set_model(m_model()); + if (batchMode && options.multiDisplayMode) { + updateUnchangedEntry(); + } + } +} + + +void ClutComboBox::updateUnchangedEntry() +{ + auto c = m_model()->children(); + + if (batchMode) { + if (c.empty() || c[c.size()-1][m_columns().clutFilename] != "NULL") { + Gtk::TreeModel::Row row = *(m_model()->append()); + row[m_columns().label] = M("GENERAL_UNCHANGED"); + row[m_columns().clutFilename] = "NULL"; + } + } else { + if (c.size() > 0) { + Gtk::TreeModel::Row row = c[c.size()-1]; + if (row[m_columns().clutFilename] == "NULL") { + std::cout << " removing " << ((void *)this) << std::endl; + m_model()->erase(row); + } + } + } +} + ClutComboBox::ClutColumns::ClutColumns() { add( label ); add( clutFilename ); } -int ClutComboBox::fillFromDir (const Glib::ustring& path) +ClutComboBox::ClutModel::ClutModel(const Glib::ustring &path) { m_model = Gtk::TreeStore::create (m_columns); - set_model (m_model); - - const auto result = parseDir (path); - - if (result > 0) { - pack_start (m_columns.label, false); - } - - return result; + //set_model (m_model); + count = parseDir(path); } -int ClutComboBox::parseDir (const Glib::ustring& path) +int ClutComboBox::ClutModel::parseDir(const Glib::ustring& path) { - if (path.empty () || !Glib::file_test (path, Glib::FILE_TEST_IS_DIR)) { + if (path.empty() || !Glib::file_test(path, Glib::FILE_TEST_IS_DIR)) { return 0; } - const auto startedAt = std::chrono::system_clock::now (); + const auto sorted_dir_dirs = [](const Glib::ustring& path) -> std::map + { + std::map res; + + for (const auto& dir : Glib::Dir(path)) { + const std::string full_path = Glib::build_filename(path, dir); + + if (Glib::file_test(full_path, Glib::FILE_TEST_IS_DIR)) { + res.emplace(dir, full_path); + } + } + + return res; + }; + + const auto startedAt = std::chrono::system_clock::now(); // Build menu of limited directory structure using breadth-first search using Dirs = std::vector>; @@ -232,89 +321,77 @@ int ClutComboBox::parseDir (const Glib::ustring& path) Dirs currDirs; Dirs nextDirs; - currDirs.emplace_back (path, Gtk::TreeModel::Row ()); - - while (!currDirs.empty ()) { + currDirs.emplace_back(path, Gtk::TreeModel::Row()); + while (!currDirs.empty()) { for (auto& dir : currDirs) { - const auto& path = dir.first; const auto& row = dir.second; try { - for (const auto& entry : Glib::Dir (path)) { + for (const auto& entry : sorted_dir_dirs(path)) { + auto newRow = row ? *m_model->append(row.children()) : *m_model->append(); + newRow[m_columns.label] = entry.first; - const auto entryPath = Glib::build_filename (path, entry); - - if (!Glib::file_test (entryPath, Glib::FILE_TEST_IS_DIR)) { - continue; - } - - auto newRow = row ? *m_model->append (row.children ()) : *m_model->append (); - newRow[m_columns.label] = entry; - - nextDirs.emplace_back (entryPath, newRow); + nextDirs.emplace_back(entry.second, newRow); } } catch (Glib::Exception&) {} - dirs.push_back (std::move (dir)); + dirs.push_back(std::move(dir)); - if (!notifySlowParseDir (startedAt)) { - m_model->clear (); + if (!notifySlowParseDir(startedAt)) { + m_model->clear(); return 0; } } - currDirs.clear (); - currDirs.swap (nextDirs); + currDirs.clear(); + currDirs.swap(nextDirs); } } // Fill menu structure with CLUT files - Strings entries; + std::set entries; - auto fileCount = 0; + unsigned long fileCount = 0; for (const auto& dir : dirs) { - const auto& path = dir.first; const auto& row = dir.second; - entries.clear (); + entries.clear(); try { - for (const auto& entry : Glib::Dir (path)) { + for (const auto& entry : Glib::Dir(path)) { + const auto entryPath = Glib::build_filename(path, entry); - const auto entryPath = Glib::build_filename (path, entry); - - if (!Glib::file_test (entryPath, Glib::FILE_TEST_IS_REGULAR)) { + if (!Glib::file_test(entryPath, Glib::FILE_TEST_IS_REGULAR)) { continue; } - entries.push_back (entryPath); + entries.insert(entryPath); } } catch (Glib::Exception&) {} - std::sort (entries.begin (), entries.end ()); - for (const auto& entry : entries) { - - Glib::ustring name, extension, profileName; + Glib::ustring name; + Glib::ustring extension; + Glib::ustring profileName; HaldCLUT::splitClutFilename (entry, name, extension, profileName); - extension = extension.casefold (); - if (extension.compare ("tif") != 0 && extension.compare ("png") != 0) { + extension = extension.casefold(); + if (extension.compare("tif") != 0 && extension.compare("png") != 0) { continue; } - auto newRow = row ? *m_model->append (row.children ()) : *m_model->append (); + auto newRow = row ? *m_model->append(row.children()) : *m_model->append(); newRow[m_columns.label] = name; newRow[m_columns.clutFilename] = entry; ++fileCount; - if (!notifySlowParseDir (startedAt)) { - m_model->clear (); + if (!notifySlowParseDir(startedAt)) { + m_model->clear(); return 0; } } @@ -323,6 +400,11 @@ int ClutComboBox::parseDir (const Glib::ustring& path) return fileCount; } +int ClutComboBox::foundClutsCount() const +{ + return cm->count; +} + Glib::ustring ClutComboBox::getSelectedClut() { Glib::ustring result; @@ -330,7 +412,7 @@ Glib::ustring ClutComboBox::getSelectedClut() Gtk::TreeModel::Row row = *current; if ( row ) { - result = row[ m_columns.clutFilename ]; + result = row[ m_columns().clutFilename ]; } return result; @@ -339,7 +421,7 @@ Glib::ustring ClutComboBox::getSelectedClut() void ClutComboBox::setSelectedClut( Glib::ustring filename ) { if ( !filename.empty() ) { - Gtk::TreeIter found = findRowByClutFilename( m_model->children(), filename ); + Gtk::TreeIter found = findRowByClutFilename( m_model()->children(), filename ); if ( found ) { set_active( found ); @@ -354,7 +436,7 @@ Gtk::TreeIter ClutComboBox::findRowByClutFilename( Gtk::TreeModel::Children chil for( Gtk::TreeModel::Children::iterator it = childs.begin(); !result && it != childs.end(); ++it ) { Gtk::TreeModel::Row row = *it; - if ( row[ m_columns.clutFilename ] == filename ) { + if ( row[ m_columns().clutFilename ] == filename ) { result = it; } else { result = findRowByClutFilename( it->children(), filename ); @@ -363,10 +445,3 @@ Gtk::TreeIter ClutComboBox::findRowByClutFilename( Gtk::TreeModel::Children chil return result; } - -void ClutComboBox::addUnchangedEntry() -{ - Gtk::TreeModel::Row row = *(m_model->append()); - row[m_columns.label] = M("GENERAL_UNCHANGED"); - row[m_columns.clutFilename] = "NULL"; -} diff --git a/rtgui/filmsimulation.h b/rtgui/filmsimulation.h index 9979f45b3..c813f9c85 100644 --- a/rtgui/filmsimulation.h +++ b/rtgui/filmsimulation.h @@ -11,12 +11,16 @@ class ClutComboBox : public MyComboBox { public: - int fillFromDir (const Glib::ustring& path); + ClutComboBox(const Glib::ustring &path); + //int fillFromDir (const Glib::ustring& path); + int foundClutsCount() const; Glib::ustring getSelectedClut(); void setSelectedClut( Glib::ustring filename ); - void addUnchangedEntry(); - + void setBatchMode(bool yes); + private: + void updateUnchangedEntry(); // in batchMode we need to add an extra entry "(Unchanged)". We do this whenever the widget is mapped (connecting to signal_map()), unless options.multiDisplayMode (see the comment below about cm2 in this case) + class ClutColumns : public Gtk::TreeModel::ColumnRecord { public: @@ -25,11 +29,24 @@ private: ClutColumns(); }; - int parseDir (const Glib::ustring& path); + class ClutModel { + public: + Glib::RefPtr m_model; + ClutColumns m_columns; + int count; + ClutModel(const Glib::ustring &path); + int parseDir (const Glib::ustring& path); + }; + + Glib::RefPtr &m_model(); + ClutColumns &m_columns(); + Gtk::TreeIter findRowByClutFilename( Gtk::TreeModel::Children childs, Glib::ustring filename ); - Glib::RefPtr m_model; - ClutColumns m_columns; + static std::unique_ptr cm; // we use a shared TreeModel for all the combo boxes, to save time (no need to reparse the clut dir multiple times)... + static std::unique_ptr cm2; // ... except when options.multiDisplayMode (i.e. editors in their own window), where we need two. This is because we might have two combo boxes displayed at the same time in this case + int count; // the number of clut entries + bool batchMode; }; class FilmSimulation : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel diff --git a/rtgui/filterpanel.cc b/rtgui/filterpanel.cc index a8691c1b3..5f8fa2781 100644 --- a/rtgui/filterpanel.cc +++ b/rtgui/filterpanel.cc @@ -171,15 +171,15 @@ void FilterPanel::setFilter (ExifFilterSettings& defefs, bool updateLists) } // enaFNumber->set_active (curefs.filterFNumber); - fnumberFrom->set_text (ImageMetaData::apertureToString (defefs.fnumberFrom)); + fnumberFrom->set_text (FramesMetaData::apertureToString (defefs.fnumberFrom)); curefs.fnumberFrom = defefs.fnumberFrom; - fnumberTo->set_text (ImageMetaData::apertureToString (defefs.fnumberTo)); + fnumberTo->set_text (FramesMetaData::apertureToString (defefs.fnumberTo)); curefs.fnumberTo = defefs.fnumberTo; // enaShutter->set_active (curefs.filterShutter); - shutterFrom->set_text (ImageMetaData::shutterToString (defefs.shutterFrom)); + shutterFrom->set_text (FramesMetaData::shutterToString (defefs.shutterFrom)); curefs.shutterFrom = defefs.shutterFrom; - shutterTo->set_text (ImageMetaData::shutterToString (defefs.shutterTo)); + shutterTo->set_text (FramesMetaData::shutterToString (defefs.shutterTo)); curefs.shutterTo = defefs.shutterTo; // enaISO->set_active (curefs.filterISO); @@ -315,8 +315,8 @@ ExifFilterSettings FilterPanel::getFilter () efs.focalTo = atof (focalTo->get_text().c_str()); efs.isoFrom = atoi (isoFrom->get_text().c_str()); efs.isoTo = atoi (isoTo->get_text().c_str()); - efs.shutterFrom = ImageMetaData::shutterFromString (shutterFrom->get_text()); - efs.shutterTo = ImageMetaData::shutterFromString (shutterTo->get_text()); + efs.shutterFrom = FramesMetaData::shutterFromString (shutterFrom->get_text()); + efs.shutterTo = FramesMetaData::shutterFromString (shutterTo->get_text()); efs.filterFNumber = enaFNumber->get_active (); efs.filterShutter = enaShutter->get_active (); diff --git a/rtgui/flatcurveeditorsubgroup.cc b/rtgui/flatcurveeditorsubgroup.cc index 2e690f32a..a9d51abec 100644 --- a/rtgui/flatcurveeditorsubgroup.cc +++ b/rtgui/flatcurveeditorsubgroup.cc @@ -63,9 +63,9 @@ FlatCurveEditorSubGroup::FlatCurveEditorSubGroup (CurveEditorGroup* prt, Glib::u } editCPoints = Gtk::manage (new Gtk::ToggleButton()); - initButton(*editCPoints, Glib::ustring("editmodehand.png"), Gtk::ALIGN_START, false, Glib::ustring(M("EDIT_PIPETTE_TOOLTIP"))); + initButton(*editCPoints, Glib::ustring("editmodehand.png"), Gtk::ALIGN_START, false, "EDIT_PIPETTE_TOOLTIP"); editPointCPoints = Gtk::manage (new Gtk::ToggleButton ()); - initButton(*editPointCPoints, Glib::ustring("gtk-edit.png"), Gtk::ALIGN_START, false, Glib::ustring(M("CURVEEDITOR_EDITPOINT_HINT"))); + initButton(*editPointCPoints, Glib::ustring("gtk-edit.png"), Gtk::ALIGN_START, false, "CURVEEDITOR_EDITPOINT_HINT"); copyCPoints = Gtk::manage (new Gtk::Button ()); initButton(*copyCPoints, Glib::ustring("edit-copy.png"), Gtk::ALIGN_END, true); pasteCPoints = Gtk::manage (new Gtk::Button ()); diff --git a/rtgui/flatfield.cc b/rtgui/flatfield.cc index aec6820a5..5b52ce9d2 100644 --- a/rtgui/flatfield.cc +++ b/rtgui/flatfield.cc @@ -78,7 +78,7 @@ FlatField::FlatField () : FoldableToolPanel(this, "flatfield", M("TP_FLATFIELD_L pack_start( *flatFieldBlurRadius, Gtk::PACK_SHRINK, 0); pack_start( *flatFieldClipControl, Gtk::PACK_SHRINK, 0); - flatFieldFileconn = flatFieldFile->signal_file_set().connect ( sigc::mem_fun(*this, &FlatField::flatFieldFileChanged), true); + flatFieldFileconn = flatFieldFile->signal_file_set().connect ( sigc::mem_fun(*this, &FlatField::flatFieldFileChanged)); //, true); flatFieldFileReset->signal_clicked().connect( sigc::mem_fun(*this, &FlatField::flatFieldFile_Reset), true ); flatFieldAutoSelectconn = flatFieldAutoSelect->signal_toggled().connect ( sigc::mem_fun(*this, &FlatField::flatFieldAutoSelectChanged), true); flatFieldBlurTypeconn = flatFieldBlurType->signal_changed().connect( sigc::mem_fun(*this, &FlatField::flatFieldBlurTypeChanged) ); diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc index 989ff2758..49ce25b60 100644 --- a/rtgui/guiutils.cc +++ b/rtgui/guiutils.cc @@ -247,9 +247,10 @@ void drawCrop (Cairo::RefPtr cr, int imx, int imy, int imw, int cr->set_source_rgb (0, 0, 0); } else if (options.bgcolor == 2) { cr->set_source_rgb (1, 1, 1); + } else if (options.bgcolor == 3) { + cr->set_source_rgb (0.467, 0.467, 0.467); } - cr->rectangle (imx, imy, imw + 0.5, round(c1y) + 0.5); cr->rectangle (imx, round(imy + c2y) + 0.5, imw + 0.5, round(imh - c2y) + 0.5); cr->rectangle (imx, round(imy + c1y) + 0.5, round(c1x) + 0.5, round(c2y - c1y + 1) + 0.5); @@ -1167,9 +1168,174 @@ bool MyHScale::on_key_press_event (GdkEventKey* event) } } -MyFileChooserButton::MyFileChooserButton (const Glib::ustring& title, Gtk::FileChooserAction action) : Gtk::FileChooserButton(title, action) +MyFileChooserButton::MyFileChooserButton(const Glib::ustring &title, Gtk::FileChooserAction action): + title_(title), + action_(action), + lbl_("", Gtk::ALIGN_START), + show_hidden_(false) { - //set_size_request(35, -1); + lbl_.set_ellipsize(Pango::ELLIPSIZE_MIDDLE); + lbl_.set_justify(Gtk::JUSTIFY_LEFT); + set_none(); + box_.pack_start(lbl_, true, true); + Gtk::Image *img = Gtk::manage(new Gtk::Image()); + img->set_from_icon_name("document-open", Gtk::ICON_SIZE_BUTTON); + box_.pack_start(*Gtk::manage(new Gtk::VSeparator()), false, false, 5); + box_.pack_start(*img, false, false); + box_.show_all_children(); + add(box_); + signal_clicked().connect(sigc::mem_fun(*this, &MyFileChooserButton::show_chooser)); + + if (GTK_MINOR_VERSION < 20) { + set_border_width(2); // margin doesn't work on GTK < 3.20 + } + + set_name("MyFileChooserButton"); +} + + +void MyFileChooserButton::show_chooser() +{ + Gtk::FileChooserDialog dlg(getToplevelWindow(this), title_, action_); + dlg.add_button(M("GENERAL_CANCEL"), Gtk::RESPONSE_CANCEL); + dlg.add_button(M(action_ == Gtk::FILE_CHOOSER_ACTION_SAVE ? "GENERAL_SAVE" : "GENERAL_OPEN"), Gtk::RESPONSE_OK); + dlg.set_filename(filename_); + for (auto &f : file_filters_) { + dlg.add_filter(f); + } + if (cur_filter_) { + dlg.set_filter(cur_filter_); + } + for (auto &f : shortcut_folders_) { + dlg.add_shortcut_folder(f); + } + if (!current_folder_.empty()) { + dlg.set_current_folder(current_folder_); + } + dlg.set_show_hidden(show_hidden_); + int res = dlg.run(); + if (res == Gtk::RESPONSE_OK) { + filename_ = dlg.get_filename(); + current_folder_ = dlg.get_current_folder(); + lbl_.set_label(Glib::path_get_basename(filename_)); + selection_changed_.emit(); + } +} + + +sigc::signal &MyFileChooserButton::signal_selection_changed() +{ + return selection_changed_; +} + + +sigc::signal &MyFileChooserButton::signal_file_set() +{ + return selection_changed_; +} + + +std::string MyFileChooserButton::get_filename() const +{ + return filename_; +} + + +bool MyFileChooserButton::set_filename(const std::string &filename) +{ + filename_ = filename; + if (Glib::file_test(filename_, Glib::FILE_TEST_EXISTS)) { + lbl_.set_label(Glib::path_get_basename(filename_)); + } else { + set_none(); + } + return true; +} + + +void MyFileChooserButton::add_filter(const Glib::RefPtr &filter) +{ + file_filters_.push_back(filter); +} + + +void MyFileChooserButton::remove_filter(const Glib::RefPtr &filter) +{ + auto it = std::find(file_filters_.begin(), file_filters_.end(), filter); + if (it != file_filters_.end()) { + file_filters_.erase(it); + } +} + + +void MyFileChooserButton::set_filter(const Glib::RefPtr &filter) +{ + cur_filter_ = filter; +} + + +std::vector> MyFileChooserButton::list_filters() +{ + return file_filters_; +} + + +bool MyFileChooserButton::set_current_folder(const std::string &filename) +{ + current_folder_ = filename; + if (action_ == Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER) { + set_filename(filename); + } + return true; +} + +std::string MyFileChooserButton::get_current_folder() const +{ + return current_folder_; +} + + +bool MyFileChooserButton::add_shortcut_folder(const std::string &folder) +{ + shortcut_folders_.push_back(folder); + return true; +} + + +bool MyFileChooserButton::remove_shortcut_folder(const std::string &folder) +{ + auto it = std::find(shortcut_folders_.begin(), shortcut_folders_.end(), folder); + if (it != shortcut_folders_.end()) { + shortcut_folders_.erase(it); + } + return true; +} + + +void MyFileChooserButton::unselect_all() +{ + filename_ = ""; + set_none(); +} + + +void MyFileChooserButton::unselect_filename(const std::string &filename) +{ + if (filename_ == filename) { + unselect_all(); + } +} + + +void MyFileChooserButton::set_show_hidden(bool yes) +{ + show_hidden_ = yes; +} + + +void MyFileChooserButton::set_none() +{ + lbl_.set_label(Glib::ustring("(") + M("GENERAL_NONE") + ")"); } // For an unknown reason (a bug ?), it doesn't work when action = FILE_CHOOSER_ACTION_SELECT_FOLDER ! @@ -1178,7 +1344,7 @@ bool MyFileChooserButton::on_scroll_event (GdkEventScroll* event) // If Shift is pressed, the widget is modified if (event->state & GDK_SHIFT_MASK) { - Gtk::FileChooserButton::on_scroll_event(event); + Gtk::Button::on_scroll_event(event); return true; } @@ -1196,19 +1362,6 @@ void MyFileChooserButton::get_preferred_width_for_height_vfunc (int height, int } -void bindCurrentFolder (Gtk::FileChooser& chooser, Glib::ustring& variable) -{ - chooser.signal_selection_changed ().connect ([&]() - { - const auto current_folder = chooser.get_current_folder (); - - if (!current_folder.empty ()) - variable = current_folder; - }); - - if (!variable.empty ()) - chooser.set_current_folder (variable); -} TextOrIcon::TextOrIcon (Glib::ustring fname, Glib::ustring labelTx, Glib::ustring tooltipTx, TOITypes type) { diff --git a/rtgui/guiutils.h b/rtgui/guiutils.h index 7a71fc399..2861b4913 100644 --- a/rtgui/guiutils.h +++ b/rtgui/guiutils.h @@ -358,22 +358,72 @@ class MyHScale : public Gtk::HScale /** * @brief subclass of Gtk::FileChooserButton in order to handle the scrollwheel */ -class MyFileChooserButton : public Gtk::FileChooserButton -{ +class MyFileChooserButton: public Gtk::Button { +private: + void show_chooser(); + + Glib::ustring title_; + Gtk::FileChooserAction action_; + Gtk::HBox box_; + Gtk::Label lbl_; + std::string filename_; + std::string current_folder_; + std::vector> file_filters_; + Glib::RefPtr cur_filter_; + std::vector shortcut_folders_; + bool show_hidden_; + sigc::signal selection_changed_; protected: bool on_scroll_event (GdkEventScroll* event); void get_preferred_width_vfunc (int &minimum_width, int &natural_width) const; void get_preferred_width_for_height_vfunc (int height, int &minimum_width, int &natural_width) const; + void set_none(); + public: - MyFileChooserButton (const Glib::ustring& title, Gtk::FileChooserAction action = Gtk::FILE_CHOOSER_ACTION_OPEN); + MyFileChooserButton(const Glib::ustring &title, Gtk::FileChooserAction action=Gtk::FILE_CHOOSER_ACTION_OPEN); + + sigc::signal &signal_selection_changed(); + sigc::signal &signal_file_set(); + + std::string get_filename() const; + bool set_filename(const std::string &filename); + + void add_filter(const Glib::RefPtr &filter); + void remove_filter(const Glib::RefPtr &filter); + void set_filter(const Glib::RefPtr &filter); + std::vector> list_filters(); + + bool set_current_folder(const std::string &filename); + std::string get_current_folder() const; + + bool add_shortcut_folder(const std::string &folder); + bool remove_shortcut_folder(const std::string &folder); + + void unselect_all(); + void unselect_filename(const std::string &filename); + + void set_show_hidden(bool yes); }; /** * @brief A helper method to connect the current folder property of a file chooser to an arbitrary variable. */ -void bindCurrentFolder (Gtk::FileChooser& chooser, Glib::ustring& variable); +template +void bindCurrentFolder (FileChooser& chooser, Glib::ustring& variable) +{ + chooser.signal_selection_changed ().connect ([&]() + { + const auto current_folder = chooser.get_current_folder (); + + if (!current_folder.empty ()) + variable = current_folder; + }); + + if (!variable.empty ()) + chooser.set_current_folder (variable); +} typedef enum RTUpdatePolicy { RTUP_STATIC, diff --git a/rtgui/history.cc b/rtgui/history.cc index 72c61b678..d62fcdb30 100644 --- a/rtgui/history.cc +++ b/rtgui/history.cc @@ -24,18 +24,11 @@ using namespace rtengine; using namespace rtengine::procparams; -Glib::ustring eventDescrArray[NUMOFEVENTS]; History::History (bool bookmarkSupport) : historyVPaned(nullptr), blistener(nullptr), tpc (nullptr), bmnum (1) { blistenerLock = false; // sets default that the Before preview will not be locked - - // fill history event message array - for (int i = 0; i < NUMOFEVENTS; i++) { - eventDescrArray[i] = M(Glib::ustring::compose("HISTORY_MSG_%1", i + 1)); - } - // History List // ~~~~~~~~~~~~ Gtk::ScrolledWindow* hscrollw = Gtk::manage (new Gtk::ScrolledWindow ()); @@ -238,7 +231,7 @@ void History::procParamsChanged (ProcParams* params, ProcEvent ev, Glib::ustring } // construct formatted list content - Glib::ustring text = Glib::ustring::compose ("%1", eventDescrArray[ev]); + Glib::ustring text = M("HISTORY_MSG_" + std::to_string(ev + 1)); Glib::RefPtr selection = hTreeView->get_selection(); Gtk::TreeModel::iterator iter = selection->get_selected(); @@ -263,9 +256,8 @@ void History::procParamsChanged (ProcParams* params, ProcEvent ev, Glib::ustring // if there is no last item or its chev!=ev, create a new one if (size == 0 || !row || row[historyColumns.chev] != ev || ev == EvProfileChanged) { Gtk::TreeModel::Row newrow = *(historyModel->append()); - newrow[historyColumns.realText] = eventDescrArray[ev]; newrow[historyColumns.text] = text; - newrow[historyColumns.value] = descr; + newrow[historyColumns.value] = g_markup_escape_text(descr.c_str(), -1); newrow[historyColumns.chev] = ev; newrow[historyColumns.params] = *params; newrow[historyColumns.paramsEdited] = paramsEdited ? *paramsEdited : defParamsEdited; @@ -282,9 +274,8 @@ void History::procParamsChanged (ProcParams* params, ProcEvent ev, Glib::ustring } // else just update it else { - row[historyColumns.realText] = eventDescrArray[ev]; row[historyColumns.text] = text; - row[historyColumns.value] = descr; + row[historyColumns.value] = g_markup_escape_text(descr.c_str(), -1); row[historyColumns.chev] = ev; row[historyColumns.params] = *params; row[historyColumns.paramsEdited] = paramsEdited ? *paramsEdited : defParamsEdited; @@ -428,9 +419,9 @@ bool History::on_query_tooltip(int x, int y, bool keyboard_tooltip, const Glib:: if (path && !path.empty()) { Gtk::TreeModel::iterator iter = historyModel->get_iter(path); if (iter) { - Glib::ustring param, val; - iter->get_value(1, param); - iter->get_value(2, val); + Glib::ustring text, val; + iter->get_value(0, text); + iter->get_value(1, val); /* * @@ -449,7 +440,7 @@ bool History::on_query_tooltip(int x, int y, bool keyboard_tooltip, const Glib:: tooltip->set_custom(*hbox); */ - tooltip->set_text(param+" : "+val); + tooltip->set_text(text + " : " + val); displayTooltip = true; } } diff --git a/rtgui/history.h b/rtgui/history.h index e905cb396..8fbe256e4 100644 --- a/rtgui/history.h +++ b/rtgui/history.h @@ -40,7 +40,6 @@ public: class HistoryColumns : public Gtk::TreeModel::ColumnRecord { public: - Gtk::TreeModelColumn realText; Gtk::TreeModelColumn text; Gtk::TreeModelColumn value; Gtk::TreeModelColumn params; @@ -49,7 +48,6 @@ public: HistoryColumns() { add(text); - add(realText); add(value); add(chev); add(params); diff --git a/rtgui/icmpanel.cc b/rtgui/icmpanel.cc index 1bb1c23a3..e026243be 100644 --- a/rtgui/icmpanel.cc +++ b/rtgui/icmpanel.cc @@ -958,7 +958,7 @@ void ICMPanel::oBPCChanged () } } -void ICMPanel::setRawMeta (bool raw, const rtengine::ImageData* pMeta) +void ICMPanel::setRawMeta (bool raw, const rtengine::FramesData* pMeta) { disableListener (); diff --git a/rtgui/icmpanel.h b/rtgui/icmpanel.h index 35017bed4..f8c762b0e 100644 --- a/rtgui/icmpanel.h +++ b/rtgui/icmpanel.h @@ -122,7 +122,7 @@ public: void applyBaselineExposureOffsetChanged(); void applyHueSatMapChanged(); - void setRawMeta (bool raw, const rtengine::ImageData* pMeta); + void setRawMeta (bool raw, const rtengine::FramesData* pMeta); void saveReferencePressed (); void setICMPanelListener (ICMPanelListener* ipl) diff --git a/rtgui/indclippedpanel.cc b/rtgui/indclippedpanel.cc index 72180b31a..ae7cff644 100644 --- a/rtgui/indclippedpanel.cc +++ b/rtgui/indclippedpanel.cc @@ -24,38 +24,49 @@ IndicateClippedPanel::IndicateClippedPanel (ImageArea* ia) : imageArea(ia) { + iFon = new RTImage ("previewmodeF-focusScreen-on.png"); + iFoff = new RTImage ("previewmodeF-focusScreen-off.png"); + + previewFocusMask = Gtk::manage (new Gtk::ToggleButton ()); + previewFocusMask->set_relief(Gtk::RELIEF_NONE); + previewFocusMask->set_tooltip_markup (M("MAIN_TOOLTIP_PREVIEWFOCUSMASK")); + previewFocusMask->set_image(*iFoff); + Glib::ustring tt; - indclippedh = Gtk::manage (new Gtk::ToggleButton ()); - indclippedh->set_relief(Gtk::RELIEF_NONE); - indclippedh->add (*Gtk::manage (new RTImage ("warnhl.png"))); + indClippedH = Gtk::manage (new Gtk::ToggleButton ()); + indClippedH->set_relief(Gtk::RELIEF_NONE); + indClippedH->add (*Gtk::manage (new RTImage ("warnhl.png"))); tt = Glib::ustring::compose("%1\n%2 = %3", M("MAIN_TOOLTIP_INDCLIPPEDH"), M("MAIN_TOOLTIP_THRESHOLD"), options.highlightThreshold); if (tt.find("<") == Glib::ustring::npos && tt.find(">") == Glib::ustring::npos) { - indclippedh->set_tooltip_text (tt); + indClippedH->set_tooltip_text (tt); } else { - indclippedh->set_tooltip_markup (tt); + indClippedH->set_tooltip_markup (tt); } - indclippeds = Gtk::manage (new Gtk::ToggleButton ()); - indclippeds->set_relief(Gtk::RELIEF_NONE); - indclippeds->add (*Gtk::manage (new RTImage ("warnsh.png"))); + indClippedS = Gtk::manage (new Gtk::ToggleButton ()); + indClippedS->set_relief(Gtk::RELIEF_NONE); + indClippedS->add (*Gtk::manage (new RTImage ("warnsh.png"))); tt = Glib::ustring::compose("%1\n%2 = %3", M("MAIN_TOOLTIP_INDCLIPPEDS"), M("MAIN_TOOLTIP_THRESHOLD"), options.shadowThreshold); if (tt.find("<") == Glib::ustring::npos && tt.find(">") == Glib::ustring::npos) { - indclippeds->set_tooltip_text (tt); + indClippedS->set_tooltip_text (tt); } else { - indclippeds->set_tooltip_markup (tt); + indClippedS->set_tooltip_markup (tt); } - indclippedh->set_active (options.showClippedHighlights); - indclippeds->set_active (options.showClippedShadows); + previewFocusMask->set_active (false); + indClippedH->set_active (options.showClippedHighlights); + indClippedS->set_active (options.showClippedShadows); - pack_start (*indclippeds, Gtk::PACK_SHRINK, 0); - pack_start (*indclippedh, Gtk::PACK_SHRINK, 0); + pack_start (*previewFocusMask, Gtk::PACK_SHRINK, 0); + pack_start (*indClippedS, Gtk::PACK_SHRINK, 0); + pack_start (*indClippedH, Gtk::PACK_SHRINK, 0); - indclippedh->signal_toggled().connect( sigc::mem_fun(*this, &IndicateClippedPanel::buttonToggled) ); - indclippeds->signal_toggled().connect( sigc::mem_fun(*this, &IndicateClippedPanel::buttonToggled) ); + connFocusMask = previewFocusMask->signal_toggled().connect( sigc::bind(sigc::mem_fun(*this, &IndicateClippedPanel::buttonToggled), previewFocusMask) ); + connClippedS = indClippedS->signal_toggled().connect( sigc::bind(sigc::mem_fun(*this, &IndicateClippedPanel::buttonToggled), indClippedS) ); + connClippedH = indClippedH->signal_toggled().connect( sigc::bind(sigc::mem_fun(*this, &IndicateClippedPanel::buttonToggled), indClippedH) ); show_all (); } @@ -64,14 +75,41 @@ IndicateClippedPanel::IndicateClippedPanel (ImageArea* ia) : imageArea(ia) void IndicateClippedPanel::toggleClipped (bool highlights) { if (highlights) { - indclippedh->set_active(!indclippedh->get_active()); + indClippedH->set_active(!indClippedH->get_active()); } else { - indclippeds->set_active(!indclippeds->get_active()); + indClippedS->set_active(!indClippedS->get_active()); } } -void IndicateClippedPanel::buttonToggled () +void IndicateClippedPanel::toggleFocusMask () { + previewFocusMask->set_active(!previewFocusMask->get_active()); +} + +void IndicateClippedPanel::buttonToggled (Gtk::ToggleButton* tb) +{ + + connFocusMask.block(true); + connClippedS.block(true); + connClippedH.block(true); + + if (tb != previewFocusMask) { + previewFocusMask->set_active(false); + } else { + if (indClippedS->get_active()) { + indClippedS->set_active(false); + } + if (indClippedH->get_active()) { + indClippedH->set_active(false); + } + } + + previewFocusMask->set_image(previewFocusMask->get_active() ? *iFon : *iFoff); + + connFocusMask.block(false); + connClippedS.block(false); + connClippedH.block(false); + imageArea->queue_draw (); // this will redraw the linked Before image area @@ -80,3 +118,9 @@ void IndicateClippedPanel::buttonToggled () imageArea->iLinkedImageArea->queue_draw (); } } + +IndicateClippedPanel::~IndicateClippedPanel () +{ + delete iFon; + delete iFoff; +} diff --git a/rtgui/indclippedpanel.h b/rtgui/indclippedpanel.h index 3a6bc5296..1da4b61de 100644 --- a/rtgui/indclippedpanel.h +++ b/rtgui/indclippedpanel.h @@ -25,24 +25,34 @@ class IndicateClippedPanel : public Gtk::HBox { protected: - Gtk::ToggleButton* indclippedh; - Gtk::ToggleButton* indclippeds; + Gtk::Image* iFon, *iFoff; + Gtk::ToggleButton* previewFocusMask; + Gtk::ToggleButton* indClippedH; + Gtk::ToggleButton* indClippedS; ImageArea* imageArea; public: - explicit IndicateClippedPanel (ImageArea* ia); + explicit IndicateClippedPanel(ImageArea* ia); + ~IndicateClippedPanel(); - void buttonToggled (); + void buttonToggled(Gtk::ToggleButton* tb); + void toggleClipped(bool highlights); // inverts a toggle programmatically + void toggleFocusMask(); - void toggleClipped (bool highlights); // inverts a toggle programmatically + sigc::connection connFocusMask, connClippedS, connClippedH; - bool showClippedShadows () + + bool showFocusMask () { - return indclippeds->get_active (); + return previewFocusMask->get_active (); } - bool showClippedHighlights () + bool showClippedShadows() { - return indclippedh->get_active (); + return indClippedS->get_active(); + } + bool showClippedHighlights() + { + return indClippedH->get_active(); } }; diff --git a/rtgui/inspector.cc b/rtgui/inspector.cc index 8af99b2ab..4084e300f 100644 --- a/rtgui/inspector.cc +++ b/rtgui/inspector.cc @@ -59,7 +59,7 @@ InspectorBuffer::~InspectorBuffer() { //int InspectorBuffer::infoFromImage (const Glib::ustring& fname) //{ // -// rtengine::ImageMetaData* idata = rtengine::ImageMetaData::fromFile (fname, nullptr); +// rtengine::FramesMetaData* idata = rtengine::FramesMetaData::fromFile (fname, nullptr, true); // // if (!idata) { // return 0; diff --git a/rtgui/iptcpanel.cc b/rtgui/iptcpanel.cc index 5ee533e2c..cd0fe4050 100644 --- a/rtgui/iptcpanel.cc +++ b/rtgui/iptcpanel.cc @@ -434,7 +434,7 @@ void IPTCPanel::setDefaults (const ProcParams* defParams, const ParamsEdited* pe defChangeList = defParams->iptc; } -void IPTCPanel::setImageData (const ImageMetaData* id) +void IPTCPanel::setImageData (const FramesMetaData* id) { if (id) { diff --git a/rtgui/iptcpanel.h b/rtgui/iptcpanel.h index 63309cc27..b216cf638 100644 --- a/rtgui/iptcpanel.h +++ b/rtgui/iptcpanel.h @@ -75,7 +75,7 @@ public: void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr); void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr); - void setImageData (const rtengine::ImageMetaData* id); + void setImageData (const rtengine::FramesMetaData* id); void notifyListener (); diff --git a/rtgui/lensprofile.cc b/rtgui/lensprofile.cc index 0855ef03f..f5c9a11ab 100644 --- a/rtgui/lensprofile.cc +++ b/rtgui/lensprofile.cc @@ -22,15 +22,83 @@ #include "../rtengine/lcp.h" #include #include "rtimage.h" +#include "../rtengine/rtlensfun.h" +#include +#include using namespace rtengine; using namespace rtengine::procparams; -LensProfilePanel::LensProfilePanel () : FoldableToolPanel(this, "lensprof", M("TP_LENSPROFILE_LABEL")), lcpFileChanged(false), useDistChanged(false), useVignChanged(false), useCAChanged(false), isRaw(true), lensgeomLcpFill(nullptr) -{ - hbLCPFile = Gtk::manage(new Gtk::HBox()); +LensProfilePanel::LFDbHelper *LensProfilePanel::lf(nullptr); - lLCPFileHead = Gtk::manage(new Gtk::Label(M("GENERAL_FILE"))); +LensProfilePanel::LensProfilePanel () : + FoldableToolPanel(this, "lensprof", M("TP_LENSPROFILE_LABEL")), + lcModeChanged(false), + lcpFileChanged(false), + useDistChanged(false), + useVignChanged(false), + useCAChanged(false), + isRaw(true), + metadata(nullptr), + useLensfunChanged(false), + lensfunAutoChanged(false), + lensfunCameraChanged(false), + lensfunLensChanged(false) +{ + if (!lf) { + lf = new LFDbHelper(); + } + + corrUnchanged = Gtk::manage(new Gtk::RadioButton(M("GENERAL_UNCHANGED"))); + pack_start(*corrUnchanged); + + corrGroup = corrUnchanged->get_group(); + + corrOff = Gtk::manage(new Gtk::RadioButton(corrGroup, M("GENERAL_NONE"))); + pack_start(*corrOff); + + corrLensfunAuto = Gtk::manage(new Gtk::RadioButton(corrGroup, M("LENSPROFILE_CORRECTION_AUTOMATCH"))); + pack_start(*corrLensfunAuto); + + corrLensfunManual = Gtk::manage(new Gtk::RadioButton(corrGroup, M("LENSPROFILE_CORRECTION_MANUAL"))); + pack_start(*corrLensfunManual); + + lensfunCameras = Gtk::manage(new MyComboBox()); + lensfunCameras->set_model(lf->lensfunCameraModel); + lensfunCameras->pack_start(lf->lensfunModelCam.model); + Gtk::CellRendererText* cellRenderer = dynamic_cast(lensfunCameras->get_first_cell()); + cellRenderer->property_ellipsize() = Pango::ELLIPSIZE_MIDDLE; + cellRenderer->property_ellipsize_set() = true; + lensfunCameras->setPreferredWidth(50, 120); + + lensfunLenses = Gtk::manage(new MyComboBox()); + lensfunLenses->set_model(lf->lensfunLensModel); + lensfunLenses->pack_start(lf->lensfunModelLens.prettylens); + cellRenderer = dynamic_cast(lensfunLenses->get_first_cell()); + cellRenderer->property_ellipsize() = Pango::ELLIPSIZE_MIDDLE; + cellRenderer->property_ellipsize_set() = true; + lensfunLenses->setPreferredWidth(50, 120); + + Gtk::HBox *hb = Gtk::manage(new Gtk::HBox()); + hb->pack_start(*Gtk::manage(new Gtk::Label(M("EXIFFILTER_CAMERA"))), Gtk::PACK_SHRINK, 4); + hb->pack_start(*lensfunCameras); + pack_start(*hb); + + hb = Gtk::manage(new Gtk::HBox()); + hb->pack_start(*Gtk::manage(new Gtk::Label(M("EXIFFILTER_LENS"))), Gtk::PACK_SHRINK, 4); + hb->pack_start(*lensfunLenses); + warning = Gtk::manage(new Gtk::Image()); + warning->set_from_icon_name("dialog-warning", Gtk::ICON_SIZE_LARGE_TOOLBAR); + warning->set_tooltip_text(M("LENSPROFILE_LENS_WARNING")); + warning->hide(); + hb->pack_start(*warning, Gtk::PACK_SHRINK, 4); + pack_start(*hb); + + corrLcpFile = Gtk::manage(new Gtk::RadioButton(corrGroup)); + hbLCPFile = Gtk::manage(new Gtk::HBox()); + hbLCPFile->pack_start(*corrLcpFile, Gtk::PACK_SHRINK); + + lLCPFileHead = Gtk::manage(new Gtk::Label(M("LENSPROFILE_CORRECTION_LCPFILE"))); hbLCPFile->pack_start(*lLCPFileHead, Gtk::PACK_SHRINK, 4); fcbLCPFile = Gtk::manage(new MyFileChooserButton(M("TP_LENSPROFILE_LABEL"), Gtk::FILE_CHOOSER_ACTION_OPEN)); @@ -41,7 +109,7 @@ LensProfilePanel::LensProfilePanel () : FoldableToolPanel(this, "lensprof", M("T filterLCP->add_pattern("*.LCP"); fcbLCPFile->add_filter(filterLCP); - Glib::ustring defDir = lcpStore->getDefaultCommonDirectory(); + Glib::ustring defDir = LCPStore::getInstance()->getDefaultCommonDirectory(); if (!defDir.empty()) { #ifdef WIN32 @@ -55,10 +123,6 @@ LensProfilePanel::LensProfilePanel () : FoldableToolPanel(this, "lensprof", M("T hbLCPFile->pack_start(*fcbLCPFile); - btnReset = Gtk::manage(new Gtk::Button()); - btnReset->set_image (*Gtk::manage(new RTImage ("gtk-cancel.png"))); - hbLCPFile->pack_start(*btnReset, Gtk::PACK_SHRINK, 4); - pack_start(*hbLCPFile, Gtk::PACK_SHRINK, 4); ckbUseDist = Gtk::manage (new Gtk::CheckButton (M("TP_LENSPROFILE_USEDIST"))); @@ -68,12 +132,20 @@ LensProfilePanel::LensProfilePanel () : FoldableToolPanel(this, "lensprof", M("T ckbUseCA = Gtk::manage (new Gtk::CheckButton (M("TP_LENSPROFILE_USECA"))); pack_start (*ckbUseCA, Gtk::PACK_SHRINK, 4); - conLCPFile = fcbLCPFile->signal_file_set().connect( sigc::mem_fun(*this, &LensProfilePanel::onLCPFileChanged), true); - btnReset->signal_clicked().connect( sigc::mem_fun(*this, &LensProfilePanel::onLCPFileReset), true); + conLCPFile = fcbLCPFile->signal_file_set().connect( sigc::mem_fun(*this, &LensProfilePanel::onLCPFileChanged)); //, true); conUseDist = ckbUseDist->signal_toggled().connect( sigc::mem_fun(*this, &LensProfilePanel::onUseDistChanged) ); ckbUseVign->signal_toggled().connect( sigc::mem_fun(*this, &LensProfilePanel::onUseVignChanged) ); ckbUseCA->signal_toggled().connect( sigc::mem_fun(*this, &LensProfilePanel::onUseCAChanged) ); + lensfunCameras->signal_changed().connect(sigc::mem_fun(*this, &LensProfilePanel::onLensfunCameraChanged)); + lensfunLenses->signal_changed().connect(sigc::mem_fun(*this, &LensProfilePanel::onLensfunLensChanged)); + corrOff->signal_toggled().connect(sigc::mem_fun(*this, &LensProfilePanel::onCorrModeChanged)); + corrLensfunAuto->signal_toggled().connect(sigc::mem_fun(*this, &LensProfilePanel::onCorrModeChanged)); + corrLensfunManual->signal_toggled().connect(sigc::mem_fun(*this, &LensProfilePanel::onCorrModeChanged)); + corrLcpFile->signal_toggled().connect(sigc::mem_fun(*this, &LensProfilePanel::onCorrModeChanged)); + + corrUnchanged->hide(); + allowFocusDep = true; } @@ -82,35 +154,120 @@ void LensProfilePanel::read(const rtengine::procparams::ProcParams* pp, const Pa disableListener (); conUseDist.block(true); - if (!pp->lensProf.lcpFile.empty() && lcpStore->isValidLCPFileName(pp->lensProf.lcpFile)) { + if (!batchMode) { + corrUnchanged->hide(); + } + + corrLensfunAuto->set_sensitive(true); + + switch(pp->lensProf.lcMode) { + case procparams::LensProfParams::LcMode::LCP : + corrLcpFile->set_active(true); + break; + case procparams::LensProfParams::LcMode::LENSFUNAUTOMATCH : + corrLensfunAuto->set_active(true); + break; + case procparams::LensProfParams::LcMode::LENSFUNMANUAL : + corrLensfunManual->set_active(true); + break; + case procparams::LensProfParams::LcMode::NONE : + corrOff->set_active(true); + } + + if (pp->lensProf.lcpFile.empty()) { + Glib::ustring lastFolder = fcbLCPFile->get_current_folder(); + fcbLCPFile->set_current_folder(lastFolder); + fcbLCPFile->unselect_all(); + bindCurrentFolder(*fcbLCPFile, options.lastLensProfileDir); + updateDisabled(false); + } else if (LCPStore::getInstance()->isValidLCPFileName(pp->lensProf.lcpFile)) { fcbLCPFile->set_filename (pp->lensProf.lcpFile); - updateDisabled(true); - } else { - Glib::ustring fname = fcbLCPFile->get_filename(); - - if (!pp->lensProf.lcpFile.empty()) { - fcbLCPFile->unselect_filename(fname); - } else { - Glib::ustring lastFolder = fcbLCPFile->get_current_folder(); - fcbLCPFile->set_current_folder(lastFolder); - fcbLCPFile->set_filename(lastFolder + "/."); - bindCurrentFolder(*fcbLCPFile, options.lastLensProfileDir); + if(corrLcpFile->get_active()) { + updateDisabled(true); } - + } else { + fcbLCPFile->unselect_filename(fcbLCPFile->get_filename()); updateDisabled(false); } ckbUseDist->set_active (pp->lensProf.useDist); ckbUseVign->set_active (pp->lensProf.useVign && isRaw); - ckbUseCA->set_active (pp->lensProf.useCA && isRaw); + ckbUseCA->set_active(pp->lensProf.useCA && isRaw && ckbUseCA->get_sensitive()); - lcpFileChanged = useDistChanged = useVignChanged = useCAChanged = false; + const LFDatabase *db = LFDatabase::getInstance(); + LFCamera c; + + if (!setLensfunCamera(pp->lensProf.lfCameraMake, pp->lensProf.lfCameraModel) && !pp->lensProf.lfManual()) { + if (metadata) { + c = db->findCamera(metadata->getMake(), metadata->getModel()); + setLensfunCamera(c.getMake(), c.getModel()); + } + } + if (!setLensfunLens(pp->lensProf.lfLens) && !pp->lensProf.lfManual()) { + if (metadata) { + LFLens l = db->findLens(c, metadata->getLens()); + setLensfunLens(l.getLens()); + } + } + + lcModeChanged = lcpFileChanged = useDistChanged = useVignChanged = useCAChanged = false; + useLensfunChanged = lensfunAutoChanged = lensfunCameraChanged = lensfunLensChanged = false; + + if (!batchMode && !checkLensfunCanCorrect(true)) { + if (corrLensfunAuto->get_active()) { + corrOff->set_active(true); + } + corrLensfunAuto->set_sensitive(false); + } + + if (corrLensfunManual->get_active() && !checkLensfunCanCorrect(false)) { + corrOff->set_active(true); + } + + updateLensfunWarning(); enableListener (); conUseDist.block(false); } -void LensProfilePanel::setRawMeta(bool raw, const rtengine::ImageMetaData* pMeta) + +void LensProfilePanel::updateLensfunWarning() +{ + warning->hide(); + if (corrLensfunManual->get_active() || corrLensfunAuto->get_active()) { + const LFDatabase *db = LFDatabase::getInstance(); + + auto itc = lensfunCameras->get_active(); + if (!itc) { + return; + } + LFCamera c = db->findCamera((*itc)[lf->lensfunModelCam.make], (*itc)[lf->lensfunModelCam.model]); + auto itl = lensfunLenses->get_active(); + if (!itl) { + return; + } + LFLens l = db->findLens(LFCamera(), (*itl)[lf->lensfunModelLens.lens]); + float lenscrop = l.getCropFactor(); + float camcrop = c.getCropFactor(); + if (lenscrop <= 0 || camcrop <= 0 || lenscrop / camcrop >= 1.01f) { + warning->show(); + } + ckbUseVign->set_sensitive(l.hasVignettingCorrection()); + ckbUseDist->set_sensitive(l.hasDistortionCorrection()); + ckbUseCA->set_sensitive(l.hasCACorrection()); + if (!isRaw || !l.hasVignettingCorrection()) { + ckbUseVign->set_active(false); + } + if (!l.hasDistortionCorrection()) { + ckbUseDist->set_active(false); + } + if (!l.hasCACorrection()) { + ckbUseCA->set_active(false); + } + } +} + +void LensProfilePanel::setRawMeta(bool raw, const rtengine::FramesMetaData* pMeta) { if (!raw || pMeta->getFocusDist() <= 0) { disableListener(); @@ -124,11 +281,22 @@ void LensProfilePanel::setRawMeta(bool raw, const rtengine::ImageMetaData* pMeta } isRaw = raw; + metadata = pMeta; } void LensProfilePanel::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pedited) { - if (lcpStore->isValidLCPFileName(fcbLCPFile->get_filename())) { + if (corrLcpFile->get_active()) { + pp->lensProf.lcMode = procparams::LensProfParams::LcMode::LCP; + } else if(corrLensfunManual->get_active()) { + pp->lensProf.lcMode = procparams::LensProfParams::LcMode::LENSFUNMANUAL; + } else if(corrLensfunAuto->get_active()) { + pp->lensProf.lcMode = procparams::LensProfParams::LcMode::LENSFUNAUTOMATCH; + } else if(corrOff->get_active()) { + pp->lensProf.lcMode = procparams::LensProfParams::LcMode::NONE; + } + + if (LCPStore::getInstance()->isValidLCPFileName(fcbLCPFile->get_filename())) { pp->lensProf.lcpFile = fcbLCPFile->get_filename(); } else { pp->lensProf.lcpFile = ""; @@ -138,36 +306,51 @@ void LensProfilePanel::write( rtengine::procparams::ProcParams* pp, ParamsEdited pp->lensProf.useVign = ckbUseVign->get_active(); pp->lensProf.useCA = ckbUseCA->get_active(); + auto itc = lensfunCameras->get_active(); + if (itc) { + pp->lensProf.lfCameraMake = (*itc)[lf->lensfunModelCam.make]; + pp->lensProf.lfCameraModel = (*itc)[lf->lensfunModelCam.model]; + } else { + pp->lensProf.lfCameraMake = ""; + pp->lensProf.lfCameraModel = ""; + } + auto itl = lensfunLenses->get_active(); + if (itl) { + pp->lensProf.lfLens = (*itl)[lf->lensfunModelLens.lens]; + } else { + pp->lensProf.lfLens = ""; + } + if (pedited) { + pedited->lensProf.lcMode = lcModeChanged; pedited->lensProf.lcpFile = lcpFileChanged; pedited->lensProf.useDist = useDistChanged; pedited->lensProf.useVign = useVignChanged; pedited->lensProf.useCA = useCAChanged; + pedited->lensProf.useLensfun = useLensfunChanged; + pedited->lensProf.lfAutoMatch = lensfunAutoChanged; + pedited->lensProf.lfCameraMake = lensfunCameraChanged; + pedited->lensProf.lfCameraModel = lensfunCameraChanged; + pedited->lensProf.lfLens = lensfunLensChanged; } } void LensProfilePanel::onLCPFileChanged() { lcpFileChanged = true; - updateDisabled(lcpStore->isValidLCPFileName(fcbLCPFile->get_filename())); + bool valid = LCPStore::getInstance()->isValidLCPFileName(fcbLCPFile->get_filename()); + updateDisabled(valid); if (listener) { + if (valid) { + disableListener(); + corrLcpFile->set_active(true); + enableListener(); + } listener->panelChanged (EvLCPFile, Glib::path_get_basename(fcbLCPFile->get_filename())); } } -void LensProfilePanel::onLCPFileReset() -{ - lcpFileChanged = true; - - fcbLCPFile->unselect_filename(fcbLCPFile->get_filename()); - updateDisabled(false); - - if (listener) { - listener->panelChanged (EvLCPFile, M("GENERAL_NONE")); - } -} - void LensProfilePanel::onUseDistChanged() { useDistChanged = true; @@ -199,3 +382,299 @@ void LensProfilePanel::updateDisabled(bool enable) ckbUseVign->set_sensitive(enable && isRaw); ckbUseCA->set_sensitive(enable && allowFocusDep); } + +void LensProfilePanel::setBatchMode(bool yes) +{ + FoldableToolPanel::setBatchMode(yes); + if (yes) { + corrUnchanged->show(); + corrUnchanged->set_active(true); + } else { + corrUnchanged->hide(); + } +} + + +bool LensProfilePanel::setLensfunCamera(const Glib::ustring &make, const Glib::ustring &model) +{ + if (!make.empty() && !model.empty()) { + auto it = lensfunCameras->get_active(); + if (it && (*it)[lf->lensfunModelCam.make] == make && (*it)[lf->lensfunModelCam.model] == model) { + return true; + } + + // search for the active row + for (auto row : lf->lensfunCameraModel->children()) { + if (row[lf->lensfunModelCam.make] == make) { + auto &c = row.children(); + for (auto it = c.begin(), end = c.end(); it != end; ++it) { + auto &childrow = *it; + if (childrow[lf->lensfunModelCam.model] == model) { + lensfunCameras->set_active(it); + return true; + } + } + break; + } + } + } + lensfunCameras->set_active(-1); + return false; +} + + +bool LensProfilePanel::setLensfunLens(const Glib::ustring &lens) +{ + if (!lens.empty()) { + auto it = lensfunLenses->get_active(); + if (it && (*it)[lf->lensfunModelLens.lens] == lens) { + return true; + } + + bool first_maker_found = false; + for (auto row : lf->lensfunLensModel->children()) { + if (lens.find(row[lf->lensfunModelLens.lens]) == 0) { + auto &c = row.children(); + for (auto it = c.begin(), end = c.end(); it != end; ++it) { + auto &childrow = *it; + if (childrow[lf->lensfunModelLens.lens] == lens) { + lensfunLenses->set_active(it); + return true; + } + } + // we do not break immediately here, because there might be multiple makers + // sharing the same prefix (e.g. "Leica" and "Leica Camera AG"). + // therefore, we break below when the lens doesn't match any of them + first_maker_found = true; + } else if (first_maker_found) { + break; + } + } + } + lensfunLenses->set_active(-1); + return false; +} + + + +void LensProfilePanel::onLensfunCameraChanged() +{ + auto iter = lensfunCameras->get_active(); + + if (iter) { + lensfunCameraChanged = true; + + if (listener) { + disableListener(); + corrLensfunManual->set_active(true); + enableListener(); + + Glib::ustring name = (*iter)[lf->lensfunModelCam.model]; + listener->panelChanged(EvLensCorrLensfunCamera, name); + } + } + + updateLensfunWarning(); +} + + +void LensProfilePanel::onLensfunLensChanged() +{ + auto iter = lensfunLenses->get_active(); + + if (iter) { + lensfunLensChanged = true; + + if (listener) { + disableListener(); + corrLensfunManual->set_active(true); + enableListener(); + + Glib::ustring name = (*iter)[lf->lensfunModelLens.prettylens]; + listener->panelChanged(EvLensCorrLensfunLens, name); + } + } + + updateLensfunWarning(); +} + + +void LensProfilePanel::onCorrModeChanged() +{ + Glib::ustring mode; + + if (corrOff->get_active()) { + useLensfunChanged = true; + lensfunAutoChanged = true; + lcpFileChanged = true; + + ckbUseDist->set_sensitive(false); + ckbUseVign->set_sensitive(false); + ckbUseCA->set_sensitive(false); + + mode = M("GENERAL_NONE"); + } else if (corrLensfunAuto->get_active()) { + useLensfunChanged = true; + lensfunAutoChanged = true; + lcpFileChanged = true; + useDistChanged = true; + useVignChanged = true; + + ckbUseDist->set_sensitive(true); + ckbUseVign->set_sensitive(true); + ckbUseCA->set_sensitive(false); + + if (metadata) { + bool b = disableListener(); + const LFDatabase *db = LFDatabase::getInstance(); + LFCamera c = db->findCamera(metadata->getMake(), metadata->getModel()); + LFLens l = db->findLens(c, metadata->getLens()); + setLensfunCamera(c.getMake(), c.getModel()); + setLensfunLens(l.getLens()); + if (b) { + enableListener(); + } + } + + mode = M("LENSPROFILE_CORRECTION_AUTOMATCH"); + } else if (corrLensfunManual->get_active()) { + useLensfunChanged = true; + lensfunAutoChanged = true; + lcpFileChanged = true; + useDistChanged = true; + useVignChanged = true; + + ckbUseDist->set_sensitive(true); + ckbUseVign->set_sensitive(true); + ckbUseCA->set_sensitive(false); + + mode = M("LENSPROFILE_CORRECTION_MANUAL"); + } else if (corrLcpFile->get_active()) { + useLensfunChanged = true; + lensfunAutoChanged = true; + lcpFileChanged = true; + useDistChanged = true; + useVignChanged = true; + + updateDisabled(true); + + mode = M("LENSPROFILE_CORRECTION_LCPFILE"); + } else if (corrUnchanged->get_active()) { + useLensfunChanged = false; + lensfunAutoChanged = false; + lcpFileChanged = false; + lensfunCameraChanged = false; + lensfunLensChanged = false; + + ckbUseDist->set_sensitive(true); + ckbUseVign->set_sensitive(true); + ckbUseCA->set_sensitive(true); + + mode = M("GENERAL_UNCHANGED"); + } + lcModeChanged = true; + updateLensfunWarning(); + + if (listener) { + listener->panelChanged(EvLensCorrMode, mode); + } +} + + +bool LensProfilePanel::checkLensfunCanCorrect(bool automatch) +{ + if (!metadata) { + return false; + } + rtengine::procparams::ProcParams lpp; + write(&lpp); + std::unique_ptr mod(LFDatabase::findModifier(lpp.lensProf, metadata, 100, 100, lpp.coarse, -1)); + return mod.get() != nullptr; +} + + +//----------------------------------------------------------------------------- +// LFDbHelper +//----------------------------------------------------------------------------- + +LensProfilePanel::LFDbHelper::LFDbHelper() +{ +#ifdef _OPENMP +#pragma omp parallel sections +#endif +{ +#ifdef _OPENMP +#pragma omp section +#endif +{ + lensfunCameraModel = Gtk::TreeStore::create(lensfunModelCam); + fillLensfunCameras(); +} +#ifdef _OPENMP +#pragma omp section +#endif +{ + lensfunLensModel = Gtk::TreeStore::create(lensfunModelLens); + fillLensfunLenses(); +} +} +} + +void LensProfilePanel::LFDbHelper::fillLensfunCameras() +{ + if (options.rtSettings.verbose) { + std::cout << "LENSFUN, scanning cameras:" << std::endl; + } + std::map> camnames; + auto camlist = LFDatabase::getInstance()->getCameras(); + for (auto &c : camlist) { + camnames[c.getMake()].insert(c.getModel()); + + if (options.rtSettings.verbose) { + std::cout << " found: " << c.getDisplayString().c_str() << std::endl; + } + } + for (auto &p : camnames) { + Gtk::TreeModel::Row row = *(lensfunCameraModel->append()); + row[lensfunModelCam.make] = p.first; + row[lensfunModelCam.model] = p.first; + for (auto &c : p.second) { + Gtk::TreeModel::Row child = *(lensfunCameraModel->append(row.children())); + child[lensfunModelCam.make] = p.first; + child[lensfunModelCam.model] = c; + } + } +} + + +void LensProfilePanel::LFDbHelper::fillLensfunLenses() +{ + if (options.rtSettings.verbose) { + std::cout << "LENSFUN, scanning lenses:" << std::endl; + } + std::map> lenses; + auto lenslist = LFDatabase::getInstance()->getLenses(); + for (auto &l : lenslist) { + auto name = l.getLens(); + auto make = l.getMake(); + lenses[make].insert(name); + + if (options.rtSettings.verbose) { + std::cout << " found: " << l.getDisplayString().c_str() << std::endl; + } + } + for (auto &p : lenses) { + Gtk::TreeModel::Row row = *(lensfunLensModel->append()); + row[lensfunModelLens.lens] = p.first; + row[lensfunModelLens.prettylens] = p.first; + for (auto &c : p.second) { + Gtk::TreeModel::Row child = *(lensfunLensModel->append(row.children())); + child[lensfunModelLens.lens] = c; + if (c.find(p.first, p.first.size()+1) == p.first.size()+1) { + child[lensfunModelLens.prettylens] = c.substr(p.first.size()+1); + } else { + child[lensfunModelLens.prettylens] = c; + } + } + } +} diff --git a/rtgui/lensprofile.h b/rtgui/lensprofile.h index 9543721a0..e70515470 100644 --- a/rtgui/lensprofile.h +++ b/rtgui/lensprofile.h @@ -32,32 +32,80 @@ protected: MyFileChooserButton *fcbLCPFile; Gtk::CheckButton *ckbUseDist, *ckbUseVign, *ckbUseCA; Gtk::HBox *hbLCPFile; - Gtk::Button *btnReset; Gtk::Label *lLCPFileHead; - bool lcpFileChanged, useDistChanged, useVignChanged, useCAChanged; + bool lcModeChanged, lcpFileChanged, useDistChanged, useVignChanged, useCAChanged; sigc::connection conLCPFile, conUseDist, conUseVign, conUseCA; void updateDisabled(bool enable); bool allowFocusDep; bool isRaw; - LensGeometry *lensgeomLcpFill; + const rtengine::FramesMetaData* metadata; + Gtk::RadioButton::Group corrGroup; + Gtk::RadioButton *corrOff; + Gtk::RadioButton *corrLensfunAuto; + Gtk::RadioButton *corrLensfunManual; + Gtk::RadioButton *corrLcpFile; + Gtk::RadioButton *corrUnchanged; + MyComboBox *lensfunCameras; + MyComboBox *lensfunLenses; + Gtk::Image *warning; + + class LFDbHelper { + public: + class LFModelCam: public Gtk::TreeModel::ColumnRecord { + public: + LFModelCam() { add(make); add(model); } + Gtk::TreeModelColumn make; + Gtk::TreeModelColumn model; + }; + + class LFModelLens: public Gtk::TreeModel::ColumnRecord { + public: + LFModelLens() { add(lens); add(prettylens); } + Gtk::TreeModelColumn lens; + Gtk::TreeModelColumn prettylens; + }; + + LFModelCam lensfunModelCam; + LFModelLens lensfunModelLens; + + Glib::RefPtr lensfunCameraModel; + Glib::RefPtr lensfunLensModel; + + LFDbHelper(); + void fillLensfunCameras(); + void fillLensfunLenses(); + }; + static LFDbHelper *lf; + + bool useLensfunChanged; + bool lensfunAutoChanged; + bool lensfunCameraChanged; + bool lensfunLensChanged; + + bool setLensfunCamera(const Glib::ustring &make, const Glib::ustring &model); + bool setLensfunLens(const Glib::ustring &lens); + bool checkLensfunCanCorrect(bool automatch); + void updateLensfunWarning(); + public: LensProfilePanel (); void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr); void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr); - void setRawMeta (bool raw, const rtengine::ImageMetaData* pMeta); + void setRawMeta (bool raw, const rtengine::FramesMetaData* pMeta); void onLCPFileChanged (); - void onLCPFileReset (); void onUseDistChanged(); void onUseVignChanged(); void onUseCAChanged(); - void setLensGeomRef( LensGeometry *foo) - { - lensgeomLcpFill = foo ; - }; + + void setBatchMode(bool yes); + + void onLensfunCameraChanged(); + void onLensfunLensChanged(); + void onCorrModeChanged(); }; #endif diff --git a/rtgui/main-cli.cc b/rtgui/main-cli.cc index 69c3d8487..1d1917e8c 100644 --- a/rtgui/main-cli.cc +++ b/rtgui/main-cli.cc @@ -96,14 +96,14 @@ bool fast_export = false; * -1 if there is an error in parameters * -2 if an error occurred during processing * -3 if at least one required procparam file was not found */ -int processLineParams( int argc, char **argv ); +int processLineParams ( int argc, char **argv ); -bool dontLoadCache( int argc, char **argv ); +bool dontLoadCache ( int argc, char **argv ); -int main(int argc, char **argv) +int main (int argc, char **argv) { - setlocale(LC_ALL, ""); - setlocale(LC_NUMERIC, "C"); // to set decimal point to "." + setlocale (LC_ALL, ""); + setlocale (LC_NUMERIC, "C"); // to set decimal point to "." Gio::init (); @@ -116,57 +116,62 @@ int main(int argc, char **argv) #ifdef WIN32 WCHAR exnameU[512] = {0}; GetModuleFileNameW (NULL, exnameU, 511); - WideCharToMultiByte(CP_UTF8, 0, exnameU, -1, exname, 511, 0, 0 ); + WideCharToMultiByte (CP_UTF8, 0, exnameU, -1, exname, 511, 0, 0 ); #else - if (readlink("/proc/self/exe", exname, 511) < 0) { - strncpy(exname, argv[0], 511); + if (readlink ("/proc/self/exe", exname, 511) < 0) { + strncpy (exname, argv[0], 511); } #endif - exePath = Glib::path_get_dirname(exname); + exePath = Glib::path_get_dirname (exname); // set paths - if (Glib::path_is_absolute(DATA_SEARCH_PATH)) { + if (Glib::path_is_absolute (DATA_SEARCH_PATH)) { argv0 = DATA_SEARCH_PATH; } else { - argv0 = Glib::build_filename(exePath, DATA_SEARCH_PATH); + argv0 = Glib::build_filename (exePath, DATA_SEARCH_PATH); } - if (Glib::path_is_absolute(CREDITS_SEARCH_PATH)) { + if (Glib::path_is_absolute (CREDITS_SEARCH_PATH)) { creditsPath = CREDITS_SEARCH_PATH; } else { - creditsPath = Glib::build_filename(exePath, CREDITS_SEARCH_PATH); + creditsPath = Glib::build_filename (exePath, CREDITS_SEARCH_PATH); } - if (Glib::path_is_absolute(LICENCE_SEARCH_PATH)) { + if (Glib::path_is_absolute (LICENCE_SEARCH_PATH)) { licensePath = LICENCE_SEARCH_PATH; } else { - licensePath = Glib::build_filename(exePath, LICENCE_SEARCH_PATH); + licensePath = Glib::build_filename (exePath, LICENCE_SEARCH_PATH); } + options.rtSettings.lensfunDbDirectory = LENSFUN_DB_PATH; + #else argv0 = DATA_SEARCH_PATH; creditsPath = CREDITS_SEARCH_PATH; licensePath = LICENCE_SEARCH_PATH; + options.rtSettings.lensfunDbDirectory = LENSFUN_DB_PATH; #endif - bool quickstart = dontLoadCache(argc, argv); + bool quickstart = dontLoadCache (argc, argv); - if (!Options::load (quickstart)) { - printf("Fatal error!\nThe RT_SETTINGS and/or RT_PATH environment variables are set, but use a relative path. The path must be absolute!\n"); + try { + Options::load (quickstart); + } catch (Options::Error &) { + printf ("Fatal error!\nThe RT_SETTINGS and/or RT_PATH environment variables are set, but use a relative path. The path must be absolute!\n"); return -2; } - rtengine::setPaths(options); + rtengine::setPaths(); - TIFFSetWarningHandler(nullptr); // avoid annoying message boxes + TIFFSetWarningHandler (nullptr); // avoid annoying message boxes #ifndef WIN32 // Move the old path to the new one if the new does not exist - if (Glib::file_test(Glib::build_filename(options.rtdir, "cache"), Glib::FILE_TEST_IS_DIR) && !Glib::file_test(options.cacheBaseDir, Glib::FILE_TEST_IS_DIR)) { - g_rename(Glib::build_filename (options.rtdir, "cache").c_str (), options.cacheBaseDir.c_str ()); + if (Glib::file_test (Glib::build_filename (options.rtdir, "cache"), Glib::FILE_TEST_IS_DIR) && !Glib::file_test (options.cacheBaseDir, Glib::FILE_TEST_IS_DIR)) { + g_rename (Glib::build_filename (options.rtdir, "cache").c_str (), options.cacheBaseDir.c_str ()); } #endif @@ -175,57 +180,58 @@ int main(int argc, char **argv) bool consoleOpened = false; // suppression of annoying error boxes - SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); + SetErrorMode (SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); if (argc > 1 || options.rtSettings.verbose) { - Glib::ustring fname(fname_to_utf8 (argv[1])); + Glib::ustring fname (fname_to_utf8 (argv[1])); #if ECLIPSE_ARGS - fname = fname.substr(1, fname.length()-2); + fname = fname.substr (1, fname.length() - 2); #endif + if (options.rtSettings.verbose || ( !Glib::file_test (fname, Glib::FILE_TEST_EXISTS ) && !Glib::file_test (fname, Glib::FILE_TEST_IS_DIR))) { - bool stdoutRedirectedtoFile = (GetFileType(GetStdHandle(STD_OUTPUT_HANDLE)) == 0x0001); - bool stderrRedirectedtoFile = (GetFileType(GetStdHandle(STD_ERROR_HANDLE)) == 0x0001); + bool stdoutRedirectedtoFile = (GetFileType (GetStdHandle (STD_OUTPUT_HANDLE)) == 0x0001); + bool stderrRedirectedtoFile = (GetFileType (GetStdHandle (STD_ERROR_HANDLE)) == 0x0001); // no console, if stdout and stderr both are redirected to file - if( !(stdoutRedirectedtoFile && stderrRedirectedtoFile)) { + if ( ! (stdoutRedirectedtoFile && stderrRedirectedtoFile)) { // check if parameter -w was passed. // We have to do that in this step, because it controls whether to open a console to show the output of following steps bool Console = true; - for(int i = 1; i < argc; i++) - if(!strcmp(argv[i], "-w")) { + for (int i = 1; i < argc; i++) + if (!strcmp (argv[i], "-w")) { Console = false; break; } - if(Console && AllocConsole()) { - AttachConsole( GetCurrentProcessId() ) ; + if (Console && AllocConsole()) { + AttachConsole ( GetCurrentProcessId() ) ; // Don't allow CTRL-C in console to terminate RT - SetConsoleCtrlHandler( NULL, true ); + SetConsoleCtrlHandler ( NULL, true ); // Set title of console char consoletitle[128]; - sprintf(consoletitle, "RawTherapee %s Console", RTVERSION); - SetConsoleTitle(consoletitle); + sprintf (consoletitle, "RawTherapee %s Console", RTVERSION); + SetConsoleTitle (consoletitle); // increase size of screen buffer COORD c; c.X = 200; c.Y = 1000; - SetConsoleScreenBufferSize( GetStdHandle( STD_OUTPUT_HANDLE ), c ); + SetConsoleScreenBufferSize ( GetStdHandle ( STD_OUTPUT_HANDLE ), c ); // Disable console-Cursor CONSOLE_CURSOR_INFO cursorInfo; cursorInfo.dwSize = 100; cursorInfo.bVisible = false; - SetConsoleCursorInfo( GetStdHandle( STD_OUTPUT_HANDLE ), &cursorInfo ); + SetConsoleCursorInfo ( GetStdHandle ( STD_OUTPUT_HANDLE ), &cursorInfo ); - if(!stdoutRedirectedtoFile) { - freopen( "CON", "w", stdout ) ; + if (!stdoutRedirectedtoFile) { + freopen ( "CON", "w", stdout ) ; } - if(!stderrRedirectedtoFile) { - freopen( "CON", "w", stderr ) ; + if (!stderrRedirectedtoFile) { + freopen ( "CON", "w", stderr ) ; } - freopen( "CON", "r", stdin ) ; + freopen ( "CON", "r", stdin ) ; consoleOpened = true; @@ -236,31 +242,34 @@ int main(int argc, char **argv) } } } + #endif int ret = 0; // printing RT's version in all case, particularly useful for the 'verbose' mode, but also for the batch processing std::cout << "RawTherapee, version " << RTVERSION << ", command line" << std::endl; + if (argc > 1) { - ret = processLineParams(argc, argv); - } - else { + ret = processLineParams (argc, argv); + } else { std::cout << "Terminating without anything to do." << std::endl; } #ifdef WIN32 - if(consoleOpened) { - printf("Press any key to exit RawTherapee\n"); - FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE)); + + if (consoleOpened) { + printf ("Press any key to exit RawTherapee\n"); + FlushConsoleInputBuffer (GetStdHandle (STD_INPUT_HANDLE)); getch(); } + #endif return ret; } -void deleteProcParams(std::vector &pparams) +void deleteProcParams (std::vector &pparams) { for (unsigned int i = 0; i < pparams.size(); i++) { pparams[i]->deleteInstance(); @@ -272,14 +281,14 @@ void deleteProcParams(std::vector &pparam } -bool dontLoadCache( int argc, char **argv ) +bool dontLoadCache ( int argc, char **argv ) { for (int iArg = 1; iArg < argc; iArg++) { - Glib::ustring currParam(argv[iArg]); + Glib::ustring currParam (argv[iArg]); #if ECLIPSE_ARGS - currParam = currParam.substr(1, currParam.length()-2); + currParam = currParam.substr (1, currParam.length() - 2); #endif - if( currParam.at(0) == '-' && currParam.at(1) == 'q' ) { + if ( currParam.length() > 1 && currParam.at(0) == '-' && currParam.at(1) == 'q' ) { return true; } } @@ -287,7 +296,7 @@ bool dontLoadCache( int argc, char **argv ) return false; } -int processLineParams( int argc, char **argv ) +int processLineParams ( int argc, char **argv ) { rtengine::procparams::PartialProfile *rawParams = nullptr, *imgParams = nullptr; std::vector inputFiles; @@ -308,311 +317,323 @@ int processLineParams( int argc, char **argv ) std::string outputType = ""; unsigned errors = 0; - for( int iArg = 1; iArg < argc; iArg++) { - Glib::ustring currParam(argv[iArg]); + for ( int iArg = 1; iArg < argc; iArg++) { + Glib::ustring currParam (argv[iArg]); + if ( currParam.empty() ) { + continue; + } #if ECLIPSE_ARGS - currParam = currParam.substr(1, currParam.length()-2); -#endif - if( currParam.at(0) == '-' ) { - switch( currParam.at(1) ) { - case 'O': - copyParamsFile = true; - - case 'o': // outputfile or dir - if( iArg + 1 < argc ) { - iArg++; - outputPath = Glib::ustring(fname_to_utf8(argv[iArg])); -#if ECLIPSE_ARGS - outputPath = outputPath.substr(1, outputPath.length()-2); -#endif - if(outputPath.substr(0,9) == "/dev/null") { - outputPath.assign("/dev/null"); // removing any useless chars or filename - outputDirectory = false; - leaveUntouched = true; - } else if(Glib::file_test (outputPath, Glib::FILE_TEST_IS_DIR)) { - outputDirectory = true; - } - } - - break; - - case 'p': // processing parameters for all inputs; all set procparams are required, so - - // RT stop if any of them can't be loaded for any reason. - if( iArg + 1 < argc ) { - iArg++; - Glib::ustring fname(fname_to_utf8(argv[iArg])); -#if ECLIPSE_ARGS - fname = fname.substr(1, fname.length()-2); + currParam = currParam.substr (1, currParam.length() - 2); #endif - if (fname.at(0) == '-') { - std::cerr << "Error: filename missing next to the -p switch" << std::endl; - deleteProcParams(processingParams); - return -3; + if ( currParam.at (0) == '-' ) { + switch ( currParam.at (1) ) { + case 'O': + copyParamsFile = true; + + case 'o': // outputfile or dir + if ( iArg + 1 < argc ) { + iArg++; + outputPath = Glib::ustring (fname_to_utf8 (argv[iArg])); +#if ECLIPSE_ARGS + outputPath = outputPath.substr (1, outputPath.length() - 2); +#endif + + if (outputPath.substr (0, 9) == "/dev/null") { + outputPath.assign ("/dev/null"); // removing any useless chars or filename + outputDirectory = false; + leaveUntouched = true; + } else if (Glib::file_test (outputPath, Glib::FILE_TEST_IS_DIR)) { + outputDirectory = true; + } } - rtengine::procparams::PartialProfile* currentParams = new rtengine::procparams::PartialProfile(true); + break; - if (!(currentParams->load ( fname ))) { - processingParams.push_back(currentParams); + case 'p': // processing parameters for all inputs; all set procparams are required, so + + // RT stop if any of them can't be loaded for any reason. + if ( iArg + 1 < argc ) { + iArg++; + Glib::ustring fname (fname_to_utf8 (argv[iArg])); +#if ECLIPSE_ARGS + fname = fname.substr (1, fname.length() - 2); +#endif + + if (fname.at (0) == '-') { + std::cerr << "Error: filename missing next to the -p switch" << std::endl; + deleteProcParams (processingParams); + return -3; + } + + rtengine::procparams::PartialProfile* currentParams = new rtengine::procparams::PartialProfile (true); + + if (! (currentParams->load ( fname ))) { + processingParams.push_back (currentParams); + } else { + std::cerr << "Error: \"" << fname << "\" not found" << std::endl; + deleteProcParams (processingParams); + return -3; + } + } + + break; + + case 'S': + skipIfNoSidecar = true; + + case 's': // Processing params next to file (file extension appended) + sideProcParams = true; + sideCarFilePos = processingParams.size(); + break; + + case 'd': + useDefault = true; + break; + + case 'q': + break; + + case 'Y': + overwriteFiles = true; + break; + + case 'a': + allExtensions = true; + break; + + case 'j': + if (currParam.length() > 2 && currParam.at (2) == 's') { + if (currParam.length() == 3) { + std::cerr << "Error: the -js switch requires a mandatory value!" << std::endl; + deleteProcParams (processingParams); + return -3; + } + + // looking for the subsampling parameter + subsampling = atoi (currParam.substr (3).c_str()); + + if (subsampling < 1 || subsampling > 3) { + std::cerr << "Error: the value accompanying the -js switch has to be in the [1-3] range!" << std::endl; + deleteProcParams (processingParams); + return -3; + } } else { - std::cerr << "Error: \"" << fname << "\" not found" << std::endl; - deleteProcParams(processingParams); - return -3; - } - } + outputType = "jpg"; + if(currParam.size() < 3) { + compression = 92; + } else { + compression = atoi (currParam.substr (2).c_str()); - break; - - case 'S': - skipIfNoSidecar = true; - - case 's': // Processing params next to file (file extension appended) - sideProcParams = true; - sideCarFilePos = processingParams.size(); - break; - - case 'd': - useDefault = true; - break; - - case 'q': - break; - - case 'Y': - overwriteFiles = true; - break; - - case 'a': - allExtensions = true; - break; - - case 'j': - if (currParam.length() > 2 && currParam.at(2) == 's') { - if (currParam.length() == 3) { - std::cerr << "Error: the -js switch requires a mandatory value!" << std::endl; - deleteProcParams(processingParams); - return -3; - } - - // looking for the subsampling parameter - subsampling = atoi(currParam.substr(3).c_str()); - - if (subsampling < 1 || subsampling > 3) { - std::cerr << "Error: the value accompanying the -js switch has to be in the [1-3] range!" << std::endl; - deleteProcParams(processingParams); - return -3; - } - } else { - outputType = "jpg"; - compression = atoi(currParam.substr(2).c_str()); - - if (compression < 0 || compression > 100) { - std::cerr << "Error: the value accompanying the -j switch has to be in the [0-100] range!" << std::endl; - deleteProcParams(processingParams); - return -3; - } - } - - break; - - case 'b': - bits = atoi(currParam.substr(2).c_str()); - - if (bits != 8 && bits != 16) { - std::cerr << "Error: specify -b8 for 8-bit or -b16 for 16-bit output." << std::endl; - deleteProcParams(processingParams); - return -3; - } - - break; - - case 't': - outputType = "tif"; - compression = ((currParam.size() < 3 || currParam.at(2) != 'z') ? 0 : 1); - break; - - case 'n': - outputType = "png"; - compression = -1; - break; - - case 'f': - fast_export = true; - break; - - case 'c': // MUST be last option - while (iArg + 1 < argc) { - iArg++; - Glib::ustring argument(fname_to_utf8(argv[iArg])); -#if ECLIPSE_ARGS - argument = argument.substr(1, argument.length()-2); -#endif - - if (!Glib::file_test (argument, Glib::FILE_TEST_EXISTS)) { - std::cout << "\"" << argument << "\" doesn't exist !" << std::endl; - continue; - } - - if (Glib::file_test (argument, Glib::FILE_TEST_IS_REGULAR)) { - bool notAll = allExtensions && !options.is_parse_extention (argument); - bool notRetained = !allExtensions && !options.has_retained_extention (argument); - if (notAll || notRetained) { - if (notAll) { - std::cout << "\"" << argument << "\" is not one of the file format to process: skipped" << std::endl; - } else if (notRetained) { - std::cout << "\"" << argument << "\" is not one of the retained file format to process: skipped" << std::endl; + if (compression < 0 || compression > 100) { + std::cerr << "Error: the value accompanying the -j switch has to be in the [0-100] range!" << std::endl; + deleteProcParams (processingParams); + return -3; } } - else { - inputFiles.emplace_back (argument); - } - continue; - } - if (Glib::file_test (argument, Glib::FILE_TEST_IS_DIR)) { + break; - auto dir = Gio::File::create_for_path (argument); - if (!dir || !dir->query_exists()) { + case 'b': + bits = atoi (currParam.substr (2).c_str()); + + if (bits != 8 && bits != 16) { + std::cerr << "Error: specify -b8 for 8-bit or -b16 for 16-bit output." << std::endl; + deleteProcParams (processingParams); + return -3; + } + + break; + + case 't': + outputType = "tif"; + compression = ((currParam.size() < 3 || currParam.at (2) != 'z') ? 0 : 1); + break; + + case 'n': + outputType = "png"; + compression = -1; + break; + + case 'f': + fast_export = true; + break; + + case 'c': // MUST be last option + while (iArg + 1 < argc) { + iArg++; + Glib::ustring argument (fname_to_utf8 (argv[iArg])); +#if ECLIPSE_ARGS + argument = argument.substr (1, argument.length() - 2); +#endif + + if (!Glib::file_test (argument, Glib::FILE_TEST_EXISTS)) { + std::cout << "\"" << argument << "\" doesn't exist !" << std::endl; continue; } - try { - - auto enumerator = dir->enumerate_children("standard::name,standard::type"); - - while (auto file = enumerator->next_file()) { - - const auto fileName = Glib::build_filename(argument, file->get_name()); - bool isDir = file->get_file_type() == Gio::FILE_TYPE_DIRECTORY; - bool notAll = allExtensions && !options.is_parse_extention(fileName); - bool notRetained = !allExtensions && !options.has_retained_extention(fileName); - - if (isDir || notAll || notRetained) { - if (isDir) { - std::cout << "\"" << fileName << "\" is a directory: skipped" << std::endl; - } else if (notAll) { - std::cout << "\"" << fileName << "\" is not one of the file format to process: skipped" << std::endl; - } else if (notRetained) { - std::cout << "\"" << fileName << "\" is not one of the retained file format to process: skipped" << std::endl; - } - continue; + if (Glib::file_test (argument, Glib::FILE_TEST_IS_REGULAR)) { + bool notAll = allExtensions && !options.is_parse_extention (argument); + bool notRetained = !allExtensions && !options.has_retained_extention (argument); + if (notAll || notRetained) { + if (notAll) { + std::cout << "\"" << argument << "\" is not one of the file format to process: skipped" << std::endl; + } else if (notRetained) { + std::cout << "\"" << argument << "\" is not one of the retained file format to process: skipped" << std::endl; } - - if (sideProcParams && skipIfNoSidecar) { - // look for the sidecar proc params - if (!Glib::file_test(fileName + paramFileExtension, Glib::FILE_TEST_EXISTS)) { - std::cout << "\"" << fileName << "\" has no side-car file: image skipped" << std::endl; - continue; - } - } - - inputFiles.emplace_back (fileName); + } else { + inputFiles.emplace_back (argument); } - } catch (Glib::Exception&) {} + continue; - continue; + } + + if (Glib::file_test (argument, Glib::FILE_TEST_IS_DIR)) { + + auto dir = Gio::File::create_for_path (argument); + + if (!dir || !dir->query_exists()) { + continue; + } + + try { + + auto enumerator = dir->enumerate_children ("standard::name,standard::type"); + + while (auto file = enumerator->next_file()) { + + const auto fileName = Glib::build_filename (argument, file->get_name()); + bool isDir = file->get_file_type() == Gio::FILE_TYPE_DIRECTORY; + bool notAll = allExtensions && !options.is_parse_extention (fileName); + bool notRetained = !allExtensions && !options.has_retained_extention (fileName); + + if (isDir || notAll || notRetained) { + if (isDir) { + std::cout << "\"" << fileName << "\" is a directory: skipped" << std::endl; + } else if (notAll) { + std::cout << "\"" << fileName << "\" is not one of the file format to process: skipped" << std::endl; + } else if (notRetained) { + std::cout << "\"" << fileName << "\" is not one of the retained file format to process: skipped" << std::endl; + } + + continue; + + } + + if (sideProcParams && skipIfNoSidecar) { + // look for the sidecar proc params + if (!Glib::file_test (fileName + paramFileExtension, Glib::FILE_TEST_EXISTS)) { + std::cout << "\"" << fileName << "\" has no side-car file: image skipped" << std::endl; + continue; + } + } + + inputFiles.emplace_back (fileName); + } + + } catch (Glib::Exception&) {} + + continue; + } + + std::cerr << "\"" << argument << "\" is neither a regular file nor a directory." << std::endl; } - std::cerr << "\"" << argument << "\" is neither a regular file nor a directory." << std::endl; + break; +#ifdef WIN32 + + case 'w': // This case is handled outside this function + break; +#endif + + case 'h': + case '?': + default: { + Glib::ustring pparamsExt = paramFileExtension.substr (1); + std::cout << " An advanced, cross-platform program for developing raw photos." << std::endl; + std::cout << std::endl; + std::cout << " Website: http://www.rawtherapee.com/" << std::endl; + std::cout << " Documentation: http://rawpedia.rawtherapee.com/" << std::endl; + std::cout << " Forum: https://discuss.pixls.us/c/software/rawtherapee" << std::endl; + std::cout << " Code and bug reports: https://github.com/Beep6581/RawTherapee" << std::endl; + std::cout << std::endl; + std::cout << "Symbols:" << std::endl; + std::cout << " indicate parameters you can change." << std::endl; + std::cout << " [Square brackets] mean the parameter is optional." << std::endl; + std::cout << " The pipe symbol | indicates a choice of one or the other." << std::endl; + std::cout << " The dash symbol - denotes a range of possible values from one to the other." << std::endl; + std::cout << std::endl; + std::cout << "Usage:" << std::endl; + std::cout << " " << Glib::path_get_basename (argv[0]) << " -c | Convert files in batch with default parameters." << std::endl; + std::cout << " " << Glib::path_get_basename (argv[0]) << " -c | Convert files in batch with your own settings." << std::endl; + std::cout << std::endl; +#ifdef WIN32 + std::cout << " -w Do not open the Windows console" << std::endl; + std::cout << std::endl; +#endif + std::cout << "Options:" << std::endl; + std::cout << " " << Glib::path_get_basename (argv[0]) << "[-o |-O ] [-q] [-a] [-s|-S] [-p [-p ...] ] [-d] [ -j[1-100] [-js<1-3>] | [-b<8|16>] [-t[z] | [-n]] ] [-Y] [-f] -c " << std::endl; + std::cout << std::endl; + std::cout << " -c Specify one or more input files or directory." << std::endl; + std::cout << " When specifying directories, Rawtherapee will look for images files that comply with the" << std::endl; + std::cout << " selected extensions (see also '-a')." << std::endl; + std::cout << " -c must be the last option." << std::endl; + std::cout << " -o | Set output file or folder." << std::endl; + std::cout << " Saves output file alongside input file if -o is not specified." << std::endl; + std::cout << " -O | Set output file or folder and copy " << pparamsExt << " file into it." << std::endl; + std::cout << " Saves output file alongside input file if -O is not specified." << std::endl; + std::cout << " -q Quick-start mode. Does not load cached files to speedup start time." << std::endl; + std::cout << " -a Process all supported image file types when specifying a folder, even those" << std::endl; + std::cout << " not currently selected in Preferences > File Browser > Parsed Extensions." << std::endl; + std::cout << " -s Use the existing sidecar file to build the processing parameters," << std::endl; + std::cout << " e.g. for photo.raw there should be a photo.raw." << pparamsExt << " file in the same folder." << std::endl; + std::cout << " If the sidecar file does not exist, neutral values will be used." << std::endl; + std::cout << " -S Like -s but skip if the sidecar file does not exist." << std::endl; + std::cout << " -p Specify processing profile to be used for all conversions." << std::endl; + std::cout << " You can specify as many sets of \"-p \" options as you like," << std::endl; + std::cout << " each will be built on top of the previous one, as explained below." << std::endl; + std::cout << " -d Use the default raw or non-raw processing profile as set in" << std::endl; + std::cout << " Preferences > Image Processing > Default Processing Profile" << std::endl; + std::cout << " -j[1-100] Specify output to be JPEG (default, if -t and -n are not set)." << std::endl; + std::cout << " Optionally, specify compression 1-100 (default value: 92)." << std::endl; + std::cout << " -js<1-3> Specify the JPEG chroma subsampling parameter, where:" << std::endl; + std::cout << " 1 = Best compression: 2x2, 1x1, 1x1 (4:2:0)" << std::endl; + std::cout << " Chroma halved vertically and horizontally." << std::endl; + std::cout << " 2 = Balanced (default): 2x1, 1x1, 1x1 (4:2:2)" << std::endl; + std::cout << " Chroma halved horizontally." << std::endl; + std::cout << " 3 = Best quality: 1x1, 1x1, 1x1 (4:4:4)" << std::endl; + std::cout << " No chroma subsampling." << std::endl; + std::cout << " -b<8|16> Specify bit depth per channel (default value: 16 for TIFF, 8 for PNG)." << std::endl; + std::cout << " Only applies to TIFF and PNG output, JPEG is always 8." << std::endl; + std::cout << " -t[z] Specify output to be TIFF." << std::endl; + std::cout << " Uncompressed by default, or deflate compression with 'z'." << std::endl; + std::cout << " -n Specify output to be compressed PNG." << std::endl; + std::cout << " Compression is hard-coded to PNG_FILTER_PAETH, Z_RLE" << std::endl; + std::cout << " -Y Overwrite output if present." << std::endl; + std::cout << " -f Use the custom fast-export processing pipeline." << std::endl; + std::cout << std::endl; + std::cout << "Your " << pparamsExt << " files can be incomplete, RawTherapee will build the final values as follows:" << std::endl; + std::cout << " 1- A new processing profile is created using neutral values," << std::endl; + std::cout << " 2- If the \"-d\" option is set, the values are overridden by those found in" << std::endl; + std::cout << " the default raw or non-raw processing profile." << std::endl; + std::cout << " 3- If one or more \"-p\" options are set, the values are overridden by those" << std::endl; + std::cout << " found in these processing profiles." << std::endl; + std::cout << " 4- If the \"-s\" or \"-S\" options are set, the values are finally overridden by those" << std::endl; + std::cout << " found in the sidecar files." << std::endl; + std::cout << " The processing profiles are processed in the order specified on the command line." << std::endl; + return -1; } - - break; -#ifdef WIN32 - - case 'w': // This case is handled outside this function - break; -#endif - - case 'h': - case '?': - default: { - Glib::ustring pparamsExt = paramFileExtension.substr(1); - std::cout << " An advanced, cross-platform program for developing raw photos." << std::endl; - std::cout << std::endl; - std::cout << " Website: http://www.rawtherapee.com/" << std::endl; - std::cout << " Documentation: http://rawpedia.rawtherapee.com/" << std::endl; - std::cout << " Forum: https://discuss.pixls.us/c/software/rawtherapee" << std::endl; - std::cout << " Code and bug reports: https://github.com/Beep6581/RawTherapee" << std::endl; - std::cout << std::endl; - std::cout << "Symbols:" << std::endl; - std::cout << " indicate parameters you can change." << std::endl; - std::cout << " [Square brackets] mean the parameter is optional." << std::endl; - std::cout << " The pipe symbol | indicates a choice of one or the other." << std::endl; - std::cout << " The dash symbol - denotes a range of possible values from one to the other." << std::endl; - std::cout << std::endl; - std::cout << "Usage:" << std::endl; - std::cout << " " << Glib::path_get_basename(argv[0]) << " -c | Convert files in batch with default parameters." << std::endl; - std::cout << " " << Glib::path_get_basename(argv[0]) << " -c | Convert files in batch with your own settings." << std::endl; - std::cout << std::endl; -#ifdef WIN32 - std::cout << " -w Do not open the Windows console" << std::endl; - std::cout << std::endl; -#endif - std::cout << "Options:" << std::endl; - std::cout << " " << Glib::path_get_basename(argv[0]) << "[-o |-O ] [-q] [-a] [-s|-S] [-p [-p ...] ] [-d] [ -j[1-100] [-js<1-3>] | [-b<8|16>] [-t[z] | [-n]] ] [-Y] [-f] -c " << std::endl; - std::cout << std::endl; - std::cout << " -c Specify one or more input files or directory." << std::endl; - std::cout << " When specifying directories, Rawtherapee will look for images files that comply with the" << std::endl; - std::cout << " selected extensions (see also '-a')." << std::endl; - std::cout << " -c must be the last option." << std::endl; - std::cout << " -o | Set output file or folder." << std::endl; - std::cout << " Saves output file alongside input file if -o is not specified." << std::endl; - std::cout << " -O | Set output file or folder and copy " << pparamsExt << " file into it." << std::endl; - std::cout << " Saves output file alongside input file if -O is not specified." << std::endl; - std::cout << " -q Quick-start mode. Does not load cached files to speedup start time." << std::endl; - std::cout << " -a Process all supported image file types when specifying a folder, even those" << std::endl; - std::cout << " not currently selected in Preferences > File Browser > Parsed Extensions." << std::endl; - std::cout << " -s Use the existing sidecar file to build the processing parameters," << std::endl; - std::cout << " e.g. for photo.raw there should be a photo.raw." << pparamsExt << " file in the same folder." << std::endl; - std::cout << " If the sidecar file does not exist, neutral values will be used." << std::endl; - std::cout << " -S Like -s but skip if the sidecar file does not exist." << std::endl; - std::cout << " -p Specify processing profile to be used for all conversions." << std::endl; - std::cout << " You can specify as many sets of \"-p \" options as you like," << std::endl; - std::cout << " each will be built on top of the previous one, as explained below." << std::endl; - std::cout << " -d Use the default raw or non-raw processing profile as set in" << std::endl; - std::cout << " Preferences > Image Processing > Default Processing Profile" << std::endl; - std::cout << " -j[1-100] Specify output to be JPEG (default, if -t and -n are not set)." << std::endl; - std::cout << " Optionally, specify compression 1-100 (default value: 92)." << std::endl; - std::cout << " -js<1-3> Specify the JPEG chroma subsampling parameter, where:" << std::endl; - std::cout << " 1 = Best compression: 2x2, 1x1, 1x1 (4:2:0)" << std::endl; - std::cout << " Chroma halved vertically and horizontally." << std::endl; - std::cout << " 2 = Balanced (default): 2x1, 1x1, 1x1 (4:2:2)" << std::endl; - std::cout << " Chroma halved horizontally." << std::endl; - std::cout << " 3 = Best quality: 1x1, 1x1, 1x1 (4:4:4)" << std::endl; - std::cout << " No chroma subsampling." << std::endl; - std::cout << " -b<8|16> Specify bit depth per channel (default value: 16 for TIFF, 8 for PNG)." << std::endl; - std::cout << " Only applies to TIFF and PNG output, JPEG is always 8." << std::endl; - std::cout << " -t[z] Specify output to be TIFF." << std::endl; - std::cout << " Uncompressed by default, or deflate compression with 'z'." << std::endl; - std::cout << " -n Specify output to be compressed PNG." << std::endl; - std::cout << " Compression is hard-coded to 6." << std::endl; - std::cout << " -Y Overwrite output if present." << std::endl; - std::cout << " -f Use the custom fast-export processing pipeline." << std::endl; - std::cout << std::endl; - std::cout << "Your " << pparamsExt << " files can be incomplete, RawTherapee will build the final values as follows:" << std::endl; - std::cout << " 1- A new processing profile is created using neutral values," << std::endl; - std::cout << " 2- If the \"-d\" option is set, the values are overridden by those found in" << std::endl; - std::cout << " the default raw or non-raw processing profile." << std::endl; - std::cout << " 3- If one or more \"-p\" options are set, the values are overridden by those" << std::endl; - std::cout << " found in these processing profiles." << std::endl; - std::cout << " 4- If the \"-s\" or \"-S\" options are set, the values are finally overridden by those" << std::endl; - std::cout << " found in the sidecar files." << std::endl; - std::cout << " The processing profiles are processed in the order specified on the command line." << std::endl; - return -1; - } } } else { - argv1 = Glib::ustring(fname_to_utf8(argv[iArg])); + argv1 = Glib::ustring (fname_to_utf8 (argv[iArg])); #if ECLIPSE_ARGS - argv1 = argv1.substr(1, argv1.length()-2); + argv1 = argv1.substr (1, argv1.length() - 2); #endif - if( outputDirectory ) { + if ( outputDirectory ) { options.savePathFolder = outputPath; options.saveUsePathTemplate = false; } else { @@ -639,41 +660,41 @@ int processLineParams( int argc, char **argv ) } } - if( !argv1.empty() ) { + if ( !argv1.empty() ) { return 1; } - if( inputFiles.empty() ) { + if ( inputFiles.empty() ) { return 2; } if (useDefault) { - rawParams = new rtengine::procparams::PartialProfile(true, true); - Glib::ustring profPath = options.findProfilePath(options.defProfRaw); + rawParams = new rtengine::procparams::PartialProfile (true, true); + Glib::ustring profPath = options.findProfilePath (options.defProfRaw); - if (options.is_defProfRawMissing() || profPath.empty() || (profPath != DEFPROFILE_DYNAMIC && rawParams->load(profPath == DEFPROFILE_INTERNAL ? DEFPROFILE_INTERNAL : Glib::build_filename(profPath, Glib::path_get_basename(options.defProfRaw) + paramFileExtension)))) { + if (options.is_defProfRawMissing() || profPath.empty() || (profPath != DEFPROFILE_DYNAMIC && rawParams->load (profPath == DEFPROFILE_INTERNAL ? DEFPROFILE_INTERNAL : Glib::build_filename (profPath, Glib::path_get_basename (options.defProfRaw) + paramFileExtension)))) { std::cerr << "Error: default raw processing profile not found" << std::endl; rawParams->deleteInstance(); delete rawParams; - deleteProcParams(processingParams); + deleteProcParams (processingParams); return -3; } - imgParams = new rtengine::procparams::PartialProfile(true); - profPath = options.findProfilePath(options.defProfImg); + imgParams = new rtengine::procparams::PartialProfile (true); + profPath = options.findProfilePath (options.defProfImg); - if (options.is_defProfImgMissing() || profPath.empty() || (profPath != DEFPROFILE_DYNAMIC && imgParams->load(profPath == DEFPROFILE_INTERNAL ? DEFPROFILE_INTERNAL : Glib::build_filename(profPath, Glib::path_get_basename(options.defProfImg) + paramFileExtension)))) { + if (options.is_defProfImgMissing() || profPath.empty() || (profPath != DEFPROFILE_DYNAMIC && imgParams->load (profPath == DEFPROFILE_INTERNAL ? DEFPROFILE_INTERNAL : Glib::build_filename (profPath, Glib::path_get_basename (options.defProfImg) + paramFileExtension)))) { std::cerr << "Error: default non-raw processing profile not found" << std::endl; imgParams->deleteInstance(); delete imgParams; rawParams->deleteInstance(); delete rawParams; - deleteProcParams(processingParams); + deleteProcParams (processingParams); return -3; } } - for( size_t iFile = 0; iFile < inputFiles.size(); iFile++) { + for ( size_t iFile = 0; iFile < inputFiles.size(); iFile++) { // Has to be reinstanciated at each profile to have a ProcParams object with default values rtengine::procparams::ProcParams currentParams; @@ -688,34 +709,34 @@ int processLineParams( int argc, char **argv ) Glib::ustring outputFile; - if( outputType.empty() ) { + if ( outputType.empty() ) { outputType = "jpg"; } - if( outputPath.empty() ) { + if ( outputPath.empty() ) { Glib::ustring s = inputFile; - Glib::ustring::size_type ext = s.find_last_of('.'); - outputFile = s.substr(0, ext) + "." + outputType; - } else if( outputDirectory ) { - Glib::ustring s = Glib::path_get_basename( inputFile ); - Glib::ustring::size_type ext = s.find_last_of('.'); - outputFile = Glib::build_filename(outputPath, s.substr(0, ext) + "." + outputType); + Glib::ustring::size_type ext = s.find_last_of ('.'); + outputFile = s.substr (0, ext) + "." + outputType; + } else if ( outputDirectory ) { + Glib::ustring s = Glib::path_get_basename ( inputFile ); + Glib::ustring::size_type ext = s.find_last_of ('.'); + outputFile = Glib::build_filename (outputPath, s.substr (0, ext) + "." + outputType); } else { if (leaveUntouched) { outputFile = outputPath; } else { Glib::ustring s = outputPath; - Glib::ustring::size_type ext = s.find_last_of('.'); - outputFile = s.substr(0, ext) + "." + outputType; + Glib::ustring::size_type ext = s.find_last_of ('.'); + outputFile = s.substr (0, ext) + "." + outputType; } } - if( inputFile == outputFile) { + if ( inputFile == outputFile) { std::cerr << "Cannot overwrite: " << inputFile << std::endl; continue; } - if( !overwriteFiles && Glib::file_test( outputFile , Glib::FILE_TEST_EXISTS ) ) { + if ( !overwriteFiles && Glib::file_test ( outputFile, Glib::FILE_TEST_EXISTS ) ) { std::cerr << outputFile << " already exists: use -Y option to overwrite. This image has been skipped." << std::endl; continue; } @@ -741,18 +762,20 @@ int processLineParams( int argc, char **argv ) if (options.defProfRaw == DEFPROFILE_DYNAMIC) { rawParams->deleteInstance(); delete rawParams; - rawParams = ProfileStore::getInstance()->loadDynamicProfile(ii->getMetaData()); + rawParams = ProfileStore::getInstance()->loadDynamicProfile (ii->getMetaData()); } + std::cout << " Merging default raw processing profile" << std::endl; - rawParams->applyTo(¤tParams); - } else { + rawParams->applyTo (¤tParams); + } else { if (options.defProfImg == DEFPROFILE_DYNAMIC) { imgParams->deleteInstance(); delete imgParams; - imgParams = ProfileStore::getInstance()->loadDynamicProfile(ii->getMetaData()); + imgParams = ProfileStore::getInstance()->loadDynamicProfile (ii->getMetaData()); } + std::cout << " Merging default non-raw processing profile" << std::endl; - imgParams->applyTo(¤tParams); + imgParams->applyTo (¤tParams); } } @@ -766,7 +789,7 @@ int processLineParams( int argc, char **argv ) Glib::ustring sideProcessingParams = inputFile + paramFileExtension; // the "load" method don't reset the procparams values anymore, so values found in the procparam file override the one of currentParams - if( !Glib::file_test( sideProcessingParams, Glib::FILE_TEST_EXISTS ) || currentParams.load ( sideProcessingParams )) { + if ( !Glib::file_test ( sideProcessingParams, Glib::FILE_TEST_EXISTS ) || currentParams.load ( sideProcessingParams )) { std::cerr << "Warning: sidecar file requested but not found for: " << sideProcessingParams << std::endl; } else { sideCarFound = true; @@ -774,15 +797,15 @@ int processLineParams( int argc, char **argv ) } } - if( processingParams.size() > i ) { + if ( processingParams.size() > i ) { std::cout << " Merging procparams #" << i << std::endl; - processingParams[i]->applyTo(¤tParams); + processingParams[i]->applyTo (¤tParams); } i++; } while (i < processingParams.size() + (sideProcParams ? 1 : 0)); - if( sideProcParams && !sideCarFound && skipIfNoSidecar ) { + if ( sideProcParams && !sideCarFound && skipIfNoSidecar ) { delete ii; errors++; std::cerr << "Error: no sidecar procparams found for: " << inputFile << std::endl; @@ -791,7 +814,7 @@ int processLineParams( int argc, char **argv ) job = rtengine::ProcessingJob::create (ii, currentParams, fast_export); - if( !job ) { + if ( !job ) { errors++; std::cerr << "Error creating processing for: " << inputFile << std::endl; ii->decreaseRef(); @@ -801,31 +824,31 @@ int processLineParams( int argc, char **argv ) // Process image rtengine::IImage16* resultImage = rtengine::processImage (job, errorCode, nullptr, options.tunnelMetaData); - if( !resultImage ) { + if ( !resultImage ) { errors++; std::cerr << "Error processing: " << inputFile << std::endl; - rtengine::ProcessingJob::destroy( job ); + rtengine::ProcessingJob::destroy ( job ); continue; } // save image to disk - if( outputType == "jpg" ) { - errorCode = resultImage->saveAsJPEG( outputFile, compression, subsampling ); - } else if( outputType == "tif" ) { - errorCode = resultImage->saveAsTIFF( outputFile, bits, compression == 0 ); - } else if( outputType == "png" ) { - errorCode = resultImage->saveAsPNG( outputFile, compression, bits ); + if ( outputType == "jpg" ) { + errorCode = resultImage->saveAsJPEG ( outputFile, compression, subsampling ); + } else if ( outputType == "tif" ) { + errorCode = resultImage->saveAsTIFF ( outputFile, bits, compression == 0 ); + } else if ( outputType == "png" ) { + errorCode = resultImage->saveAsPNG ( outputFile, bits ); } else { errorCode = resultImage->saveToFile (outputFile); } - if(errorCode) { + if (errorCode) { errors++; std::cerr << "Error saving to: " << outputFile << std::endl; } else { - if( copyParamsFile ) { + if ( copyParamsFile ) { Glib::ustring outputProcessingParams = outputFile + paramFileExtension; - currentParams.save( outputProcessingParams ); + currentParams.save ( outputProcessingParams ); } } @@ -843,7 +866,7 @@ int processLineParams( int argc, char **argv ) delete rawParams; } - deleteProcParams(processingParams); + deleteProcParams (processingParams); return errors > 0 ? -2 : 0; } diff --git a/rtgui/main.cc b/rtgui/main.cc index 731de81cd..bd8f381c4 100644 --- a/rtgui/main.cc +++ b/rtgui/main.cc @@ -33,6 +33,7 @@ #include #include #include +#include #include "options.h" #include "soundman.h" #include "rtimage.h" @@ -118,83 +119,93 @@ static void myGdkLockLeave() * -1 if there is an error in parameters * -2 if an error occurred during processing * -3 if at least one required procparam file was not found */ -int processLineParams( int argc, char **argv ) +int processLineParams ( int argc, char **argv ) { - for( int iArg = 1; iArg < argc; iArg++) { - Glib::ustring currParam(argv[iArg]); + for ( int iArg = 1; iArg < argc; iArg++) { + Glib::ustring currParam (argv[iArg]); + if ( currParam.empty() ) { + continue; + } #if ECLIPSE_ARGS - currParam = currParam.substr(1, currParam.length()-2); + currParam = currParam.substr (1, currParam.length() - 2); #endif - if( currParam.at(0) == '-' ) { - switch( currParam.at(1) ) { + + if ( currParam.at (0) == '-' ) { + switch ( currParam.at (1) ) { #ifdef WIN32 - case 'w': // This case is handled outside this function - break; + case 'w': // This case is handled outside this function + break; #endif - case 'v': - return 0; + + case 'v': + std::cout << "Using lensfun " << LF_VERSION_MAJOR << "." << LF_VERSION_MINOR << "." << LF_VERSION_MICRO << "." << LF_VERSION_BUGFIX << std::endl; + return 0; #ifndef __APPLE__ // TODO agriggio - there seems to be already some "single instance app" support for OSX in rtwindow. Disabling it here until I understand how to merge the two - case 'R': - if (!gimpPlugin) { - remote = true; - } - break; -#endif - - case 'g': - if (currParam == "-gimp") { - gimpPlugin = true; - simpleEditor = true; - remote = false; + + case 'R': + if (!gimpPlugin) { + remote = true; + } + break; - } +#endif + + case 'g': + if (currParam == "-gimp") { + gimpPlugin = true; + simpleEditor = true; + remote = false; + break; + } + // no break here on purpose - case 'h': - case '?': - default: { - Glib::ustring pparamsExt = paramFileExtension.substr(1); - std::cout << " An advanced, cross-platform program for developing raw photos." << std::endl; - std::cout << std::endl; - std::cout << " Website: http://www.rawtherapee.com/" << std::endl; - std::cout << " Documentation: http://rawpedia.rawtherapee.com/" << std::endl; - std::cout << " Forum: https://discuss.pixls.us/c/software/rawtherapee" << std::endl; - std::cout << " Code and bug reports: https://github.com/Beep6581/RawTherapee" << std::endl; - std::cout << std::endl; - std::cout << "Symbols:" << std::endl; - std::cout << " indicate parameters you can change." << std::endl; - //std::cout << " [Square brackets] mean the parameter is optional." << std::endl; - //std::cout << " The pipe symbol | indicates a choice of one or the other." << std::endl; - //std::cout << " The dash symbol - denotes a range of possible values from one to the other." << std::endl; - std::cout << std::endl; - std::cout << "Usage:" << std::endl; - std::cout << " " << Glib::path_get_basename(argv[0]) << " Start File Browser inside folder." << std::endl; - std::cout << " " << Glib::path_get_basename(argv[0]) << " Start Image Editor with file." << std::endl; - std::cout << std::endl; - std::cout << "Options:" << std::endl; + case 'h': + case '?': + default: { + Glib::ustring pparamsExt = paramFileExtension.substr (1); + std::cout << " An advanced, cross-platform program for developing raw photos." << std::endl; + std::cout << std::endl; + std::cout << " Website: http://www.rawtherapee.com/" << std::endl; + std::cout << " Documentation: http://rawpedia.rawtherapee.com/" << std::endl; + std::cout << " Forum: https://discuss.pixls.us/c/software/rawtherapee" << std::endl; + std::cout << " Code and bug reports: https://github.com/Beep6581/RawTherapee" << std::endl; + std::cout << std::endl; + std::cout << "Symbols:" << std::endl; + std::cout << " indicate parameters you can change." << std::endl; + //std::cout << " [Square brackets] mean the parameter is optional." << std::endl; + //std::cout << " The pipe symbol | indicates a choice of one or the other." << std::endl; + //std::cout << " The dash symbol - denotes a range of possible values from one to the other." << std::endl; + std::cout << std::endl; + std::cout << "Usage:" << std::endl; + std::cout << " " << Glib::path_get_basename (argv[0]) << " Start File Browser inside folder." << std::endl; + std::cout << " " << Glib::path_get_basename (argv[0]) << " Start Image Editor with file." << std::endl; + std::cout << std::endl; + std::cout << "Options:" << std::endl; #ifdef WIN32 - std::cout << " -w Do not open the Windows console" << std::endl; + std::cout << " -w Do not open the Windows console" << std::endl; #endif - std::cout << " -v Print RawTherapee version number and exit" << std::endl; + std::cout << " -v Print RawTherapee version number and exit" << std::endl; #ifndef __APPLE__ - std::cout << " -R Raise an already running RawTherapee instance (if available)" << std::endl; + std::cout << " -R Raise an already running RawTherapee instance (if available)" << std::endl; #endif - std::cout << " -h -? Display this help message" << std::endl; - return -1; - } + std::cout << " -h -? Display this help message" << std::endl; + return -1; + } } } else { if (argv1.empty()) { - argv1 = Glib::ustring(fname_to_utf8(argv[iArg])); + argv1 = Glib::ustring (fname_to_utf8 (argv[iArg])); #if ECLIPSE_ARGS - argv1 = argv1.substr(1, argv1.length()-2); + argv1 = argv1.substr (1, argv1.length() - 2); #endif } else if (gimpPlugin) { - argv2 = Glib::ustring(fname_to_utf8(argv[iArg])); + argv2 = Glib::ustring (fname_to_utf8 (argv[iArg])); break; } + if (!gimpPlugin) { break; } @@ -207,22 +218,25 @@ int processLineParams( int argc, char **argv ) bool init_rt() { - if (!Options::load ()) { + try { + Options::load(); + } catch (Options::Error &e) { + std::cout << "ERROR: " << e.get_msg() << std::endl; return false; } extProgStore->init(); SoundManager::init(); - if( !options.rtSettings.verbose ) { - TIFFSetWarningHandler(nullptr); // avoid annoying message boxes + if ( !options.rtSettings.verbose ) { + TIFFSetWarningHandler (nullptr); // avoid annoying message boxes } #ifndef WIN32 // Move the old path to the new one if the new does not exist - if (Glib::file_test(Glib::build_filename(options.rtdir, "cache"), Glib::FILE_TEST_IS_DIR) && !Glib::file_test(options.cacheBaseDir, Glib::FILE_TEST_IS_DIR)) { - g_rename(Glib::build_filename (options.rtdir, "cache").c_str (), options.cacheBaseDir.c_str ()); + if (Glib::file_test (Glib::build_filename (options.rtdir, "cache"), Glib::FILE_TEST_IS_DIR) && !Glib::file_test (options.cacheBaseDir, Glib::FILE_TEST_IS_DIR)) { + g_rename (Glib::build_filename (options.rtdir, "cache").c_str (), options.cacheBaseDir.c_str ()); } #endif @@ -239,11 +253,11 @@ void cleanup_rt() RTWindow *create_rt_window() { - Glib::ustring icon_path = Glib::build_filename(argv0, "images"); + Glib::ustring icon_path = Glib::build_filename (argv0, "images"); Glib::RefPtr defaultIconTheme = Gtk::IconTheme::get_default(); - defaultIconTheme->append_search_path(icon_path); + defaultIconTheme->append_search_path (icon_path); - rtengine::setPaths(options); + rtengine::setPaths(); MyExpander::init(); // has to stay AFTER rtengine::setPaths // ------- loading theme files @@ -251,8 +265,8 @@ RTWindow *create_rt_window() Glib::RefPtr screen = Gdk::Screen::get_default(); if (screen) { - Gtk::Settings::get_for_screen(screen)->property_gtk_theme_name() = "Adwaita"; - Gtk::Settings::get_for_screen(screen)->property_gtk_application_prefer_dark_theme() = true; + Gtk::Settings::get_for_screen (screen)->property_gtk_theme_name() = "Adwaita"; + Gtk::Settings::get_for_screen (screen)->property_gtk_application_prefer_dark_theme() = true; #if defined(__APPLE__) // This will force screen resolution regarding font, but I don't think it's compliant with Gtk guidelines... @@ -260,7 +274,7 @@ RTWindow *create_rt_window() screen->set_resolution (96.); #endif - Glib::RefPtr regex = Glib::Regex::create(THEMEREGEXSTR, Glib::RegexCompileFlags::REGEX_CASELESS); + Glib::RefPtr regex = Glib::Regex::create (THEMEREGEXSTR, Glib::RegexCompileFlags::REGEX_CASELESS); Glib::ustring filename; Glib::MatchInfo mInfo; bool match = regex->match(options.theme + ".css", mInfo); @@ -286,23 +300,26 @@ RTWindow *create_rt_window() if (!match || !Glib::file_test(filename, Glib::FILE_TEST_EXISTS)) { options.theme = "RawTherapee-GTK"; + // We're not testing GTK_MAJOR_VERSION == 3 here, since this branch requires Gtk3 only if (GTK_MINOR_VERSION < 20) { options.theme = options.theme + "3-_19"; } else { options.theme = options.theme + "3-20_"; } - filename = Glib::build_filename(argv0, "themes", options.theme + ".css"); + + filename = Glib::build_filename (argv0, "themes", options.theme + ".css"); } + cssRT = Gtk::CssProvider::create(); try { cssRT->load_from_path (filename); - Gtk::StyleContext::add_provider_for_screen(screen, cssRT, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + Gtk::StyleContext::add_provider_for_screen (screen, cssRT, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); } catch (Glib::Error &err) { - printf("Error: Can't load css file \"%s\"\nMessage: %s\n", filename.c_str(), err.what().c_str()); + printf ("Error: Can't load css file \"%s\"\nMessage: %s\n", filename.c_str(), err.what().c_str()); } catch (...) { - printf("Error: Can't load css file \"%s\"\n", filename.c_str()); + printf ("Error: Can't load css file \"%s\"\n", filename.c_str()); } // Set the font face and size @@ -311,23 +328,23 @@ RTWindow *create_rt_window() cssForced = Gtk::CssProvider::create(); //GTK318 #if GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION < 20 - cssForced->load_from_data (Glib::ustring::compose("* { font-family: %1; font-size: %2px }", options.fontFamily, options.fontSize)); + cssForced->load_from_data (Glib::ustring::compose ("* { font-family: %1; font-size: %2px }", options.fontFamily, options.fontSize)); #else - cssForced->load_from_data (Glib::ustring::compose("* { font-family: %1; font-size: %2pt }", options.fontFamily, options.fontSize)); + cssForced->load_from_data (Glib::ustring::compose ("* { font-family: %1; font-size: %2pt }", options.fontFamily, options.fontSize)); #endif //GTK318 - Gtk::StyleContext::add_provider_for_screen(screen, cssForced, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + Gtk::StyleContext::add_provider_for_screen (screen, cssForced, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); } catch (Glib::Error &err) { - printf("Error: \"%s\"\n", err.what().c_str()); + printf ("Error: \"%s\"\n", err.what().c_str()); } catch (...) { - printf("Error: Can't find the font named \"%s\"\n", options.fontFamily.c_str()); + printf ("Error: Can't find the font named \"%s\"\n", options.fontFamily.c_str()); } } } #ifndef NDEBUG else if (!screen) { - printf("ERROR: Can't get default screen!\n"); + printf ("ERROR: Can't get default screen!\n"); } #endif @@ -339,12 +356,12 @@ RTWindow *create_rt_window() // alerting users if the default raw and image profiles are missing if (options.is_defProfRawMissing()) { - Gtk::MessageDialog msgd (Glib::ustring::compose(M("OPTIONS_DEFRAW_MISSING"), options.defProfRaw), true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); + Gtk::MessageDialog msgd (Glib::ustring::compose (M ("OPTIONS_DEFRAW_MISSING"), options.defProfRaw), true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); msgd.run (); } if (options.is_defProfImgMissing()) { - Gtk::MessageDialog msgd (Glib::ustring::compose(M("OPTIONS_DEFIMG_MISSING"), options.defProfImg), true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); + Gtk::MessageDialog msgd (Glib::ustring::compose (M ("OPTIONS_DEFIMG_MISSING"), options.defProfImg), true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); msgd.run (); } @@ -352,12 +369,13 @@ RTWindow *create_rt_window() } -class RTApplication: public Gtk::Application { +class RTApplication: public Gtk::Application +{ public: RTApplication(): - Gtk::Application("com.rawtherapee.application", - Gio::APPLICATION_HANDLES_OPEN), - rtWindow(nullptr) + Gtk::Application ("com.rawtherapee.application", + Gio::APPLICATION_HANDLES_OPEN), + rtWindow (nullptr) { } @@ -366,6 +384,7 @@ public: if (rtWindow) { delete rtWindow; } + cleanup_rt(); } @@ -375,19 +394,19 @@ private: if (rtWindow) { return true; } - + if (!init_rt()) { Gtk::MessageDialog msgd ("Fatal error!\nThe RT_SETTINGS and/or RT_PATH environment variables are set, but use a relative path. The path must be absolute!", true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); - add_window(msgd); + add_window (msgd); msgd.run (); return false; } else { rtWindow = create_rt_window(); - add_window(*rtWindow); + add_window (*rtWindow); return true; } } - + // Override default signal handlers: void on_activate() override { @@ -395,9 +414,9 @@ private: rtWindow->present(); } } - - void on_open(const Gio::Application::type_vec_files& files, - const Glib::ustring& hint) override + + void on_open (const Gio::Application::type_vec_files& files, + const Glib::ustring& hint) override { if (create_window()) { struct Data { @@ -407,29 +426,30 @@ private: }; Data *d = new Data; d->filecatalog = rtWindow->fpanel->fileCatalog; - + for (const auto &f : files) { - Thumbnail *thm = cacheMgr->getEntry(f->get_path()); + Thumbnail *thm = cacheMgr->getEntry (f->get_path()); + if (thm) { - d->entries.push_back(thm); + d->entries.push_back (thm); d->lastfilename = f->get_path(); } } - + if (!d->entries.empty()) { const auto doit = - [](gpointer data) -> gboolean - { - Data *d = static_cast(data); - d->filecatalog->openRequested(d->entries); - d->filecatalog->selectImage(d->lastfilename, true); - delete d; - return FALSE; - }; - gdk_threads_add_idle(doit, d); + [] (gpointer data) -> gboolean { + Data *d = static_cast (data); + d->filecatalog->openRequested (d->entries); + d->filecatalog->selectImage (d->lastfilename, true); + delete d; + return FALSE; + }; + gdk_threads_add_idle (doit, d); } else { delete d; } + rtWindow->present(); } } @@ -454,10 +474,10 @@ void show_gimp_plugin_info_dialog(Gtk::Window *parent) } // namespace -int main(int argc, char **argv) +int main (int argc, char **argv) { - setlocale(LC_ALL, ""); - setlocale(LC_NUMERIC, "C"); // to set decimal point to "." + setlocale (LC_ALL, ""); + setlocale (LC_NUMERIC, "C"); // to set decimal point to "." simpleEditor = false; gimpPlugin = false; @@ -467,7 +487,7 @@ int main(int argc, char **argv) argv2 = ""; Glib::init(); // called by Gtk::Main, but this may be important for thread handling, so we call it ourselves now - gdk_threads_set_lock_functions(G_CALLBACK(myGdkLockEnter), (G_CALLBACK(myGdkLockLeave))); + gdk_threads_set_lock_functions (G_CALLBACK (myGdkLockEnter), (G_CALLBACK (myGdkLockLeave))); gdk_threads_init(); gtk_init (&argc, &argv); // use the "--g-fatal-warnings" command line flag to make warnings fatal Gio::init (); @@ -480,94 +500,98 @@ int main(int argc, char **argv) #ifdef WIN32 WCHAR exnameU[512] = {0}; GetModuleFileNameW (NULL, exnameU, 511); - WideCharToMultiByte(CP_UTF8, 0, exnameU, -1, exname, 511, 0, 0 ); + WideCharToMultiByte (CP_UTF8, 0, exnameU, -1, exname, 511, 0, 0 ); #else - if (readlink("/proc/self/exe", exname, 511) < 0) { - strncpy(exname, argv[0], 511); + if (readlink ("/proc/self/exe", exname, 511) < 0) { + strncpy (exname, argv[0], 511); } #endif - exePath = Glib::path_get_dirname(exname); + exePath = Glib::path_get_dirname (exname); // set paths - if (Glib::path_is_absolute(DATA_SEARCH_PATH)) { + if (Glib::path_is_absolute (DATA_SEARCH_PATH)) { argv0 = DATA_SEARCH_PATH; } else { - argv0 = Glib::build_filename(exePath, DATA_SEARCH_PATH); + argv0 = Glib::build_filename (exePath, DATA_SEARCH_PATH); } - if (Glib::path_is_absolute(CREDITS_SEARCH_PATH)) { + if (Glib::path_is_absolute (CREDITS_SEARCH_PATH)) { creditsPath = CREDITS_SEARCH_PATH; } else { - creditsPath = Glib::build_filename(exePath, CREDITS_SEARCH_PATH); + creditsPath = Glib::build_filename (exePath, CREDITS_SEARCH_PATH); } - if (Glib::path_is_absolute(LICENCE_SEARCH_PATH)) { + if (Glib::path_is_absolute (LICENCE_SEARCH_PATH)) { licensePath = LICENCE_SEARCH_PATH; } else { - licensePath = Glib::build_filename(exePath, LICENCE_SEARCH_PATH); + licensePath = Glib::build_filename (exePath, LICENCE_SEARCH_PATH); } + options.rtSettings.lensfunDbDirectory = LENSFUN_DB_PATH; + #else argv0 = DATA_SEARCH_PATH; creditsPath = CREDITS_SEARCH_PATH; licensePath = LICENCE_SEARCH_PATH; + options.rtSettings.lensfunDbDirectory = LENSFUN_DB_PATH; #endif - - + + #ifdef WIN32 bool consoleOpened = false; // suppression of annoying error boxes - SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); + SetErrorMode (SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); + + if (argc > 1) { + int ret = processLineParams ( argc, argv); - if(argc > 1) { - int ret = processLineParams( argc, argv); if (options.rtSettings.verbose || (!remote && !Glib::file_test (argv1, Glib::FILE_TEST_EXISTS ) && !Glib::file_test (argv1, Glib::FILE_TEST_IS_DIR))) { - bool stdoutRedirectedtoFile = (GetFileType(GetStdHandle(STD_OUTPUT_HANDLE)) == 0x0001); - bool stderrRedirectedtoFile = (GetFileType(GetStdHandle(STD_ERROR_HANDLE)) == 0x0001); + bool stdoutRedirectedtoFile = (GetFileType (GetStdHandle (STD_OUTPUT_HANDLE)) == 0x0001); + bool stderrRedirectedtoFile = (GetFileType (GetStdHandle (STD_ERROR_HANDLE)) == 0x0001); // no console, if stdout and stderr both are redirected to file - if( !(stdoutRedirectedtoFile && stderrRedirectedtoFile)) { + if ( ! (stdoutRedirectedtoFile && stderrRedirectedtoFile)) { // check if parameter -w was passed. // We have to do that in this step, because it controls whether to open a console to show the output of following steps bool Console = true; - for(int i = 1; i < argc; i++) - if(!strcmp(argv[i], "-w")) { + for (int i = 1; i < argc; i++) + if (!strcmp (argv[i], "-w")) { Console = false; break; } - if(Console && AllocConsole()) { - AttachConsole( GetCurrentProcessId() ) ; + if (Console && AllocConsole()) { + AttachConsole ( GetCurrentProcessId() ) ; // Don't allow CTRL-C in console to terminate RT - SetConsoleCtrlHandler( NULL, true ); + SetConsoleCtrlHandler ( NULL, true ); // Set title of console char consoletitle[128]; - sprintf(consoletitle, "RawTherapee %s Console", RTVERSION); - SetConsoleTitle(consoletitle); + sprintf (consoletitle, "RawTherapee %s Console", RTVERSION); + SetConsoleTitle (consoletitle); // increase size of screen buffer COORD c; c.X = 200; c.Y = 1000; - SetConsoleScreenBufferSize( GetStdHandle( STD_OUTPUT_HANDLE ), c ); + SetConsoleScreenBufferSize ( GetStdHandle ( STD_OUTPUT_HANDLE ), c ); // Disable console-Cursor CONSOLE_CURSOR_INFO cursorInfo; cursorInfo.dwSize = 100; cursorInfo.bVisible = false; - SetConsoleCursorInfo( GetStdHandle( STD_OUTPUT_HANDLE ), &cursorInfo ); + SetConsoleCursorInfo ( GetStdHandle ( STD_OUTPUT_HANDLE ), &cursorInfo ); - if(!stdoutRedirectedtoFile) { - freopen( "CON", "w", stdout ) ; + if (!stdoutRedirectedtoFile) { + freopen ( "CON", "w", stdout ) ; } - if(!stderrRedirectedtoFile) { - freopen( "CON", "w", stderr ) ; + if (!stderrRedirectedtoFile) { + freopen ( "CON", "w", stderr ) ; } - freopen( "CON", "r", stdin ) ; + freopen ( "CON", "r", stdin ) ; consoleOpened = true; @@ -578,10 +602,10 @@ int main(int argc, char **argv) } } - if( ret <= 0 ) { - if(consoleOpened) { - printf("Press any key to exit RawTherapee\n"); - FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE)); + if ( ret <= 0 ) { + if (consoleOpened) { + printf ("Press any key to exit RawTherapee\n"); + FlushConsoleInputBuffer (GetStdHandle (STD_INPUT_HANDLE)); getch(); } @@ -599,9 +623,9 @@ int main(int argc, char **argv) #endif if (argc > 1) { - int ret = processLineParams( argc, argv); + int ret = processLineParams ( argc, argv); - if( ret <= 0 ) { + if ( ret <= 0 ) { return ret; } } @@ -610,54 +634,59 @@ int main(int argc, char **argv) #endif if (gimpPlugin) { - if (!Glib::file_test(argv1, Glib::FILE_TEST_EXISTS) || Glib::file_test(argv1, Glib::FILE_TEST_IS_DIR)) { - printf("Error: argv1 doesn't exist\n"); + if (!Glib::file_test (argv1, Glib::FILE_TEST_EXISTS) || Glib::file_test (argv1, Glib::FILE_TEST_IS_DIR)) { + printf ("Error: argv1 doesn't exist\n"); return 1; } + if (argv2.empty()) { - printf("Error: -gimp requires two arguments\n"); + printf ("Error: -gimp requires two arguments\n"); return 1; } - } else if (!remote && Glib::file_test(argv1, Glib::FILE_TEST_EXISTS)) { + } else if (!remote && Glib::file_test(argv1, Glib::FILE_TEST_EXISTS) && !Glib::file_test(argv1, Glib::FILE_TEST_IS_DIR)) { simpleEditor = true; } int ret = 0; + if (remote) { - char *app_argv[2] = { const_cast(argv0.c_str()) }; + char *app_argv[2] = { const_cast (argv0.c_str()) }; int app_argc = 1; + if (!argv1.empty()) { app_argc = 2; - app_argv[1] = const_cast(argv1.c_str()); + app_argv[1] = const_cast (argv1.c_str()); } + RTApplication app; - ret = app.run(app_argc, app_argv); + ret = app.run (app_argc, app_argv); } else { if (init_rt()) { - Gtk::Main m(&argc, &argv); + Gtk::Main m (&argc, &argv); gdk_threads_enter(); - const std::unique_ptr rtWindow(create_rt_window()); + const std::unique_ptr rtWindow (create_rt_window()); if (gimpPlugin) { show_gimp_plugin_info_dialog(rtWindow.get()); } - m.run(*rtWindow); + m.run (*rtWindow); gdk_threads_leave(); if (gimpPlugin && - rtWindow->epanel && rtWindow->epanel->isRealized()) { + rtWindow->epanel && rtWindow->epanel->isRealized()) { SaveFormat sf; sf.format = "tif"; sf.tiffBits = 16; sf.tiffUncompressed = true; sf.saveParams = true; - - if (!rtWindow->epanel->saveImmediately(argv2, sf)) { + + if (!rtWindow->epanel->saveImmediately (argv2, sf)) { ret = -2; } } + cleanup_rt(); } else { - Gtk::Main m(&argc, &argv); + Gtk::Main m (&argc, &argv); Gtk::MessageDialog msgd ("Fatal error!\nThe RT_SETTINGS and/or RT_PATH environment variables are set, but use a relative path. The path must be absolute!", true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); msgd.run (); ret = -2; @@ -667,8 +696,8 @@ int main(int argc, char **argv) #ifdef WIN32 if (consoleOpened) { - printf("Press any key to exit RawTherapee\n"); - FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE)); + printf ("Press any key to exit RawTherapee\n"); + FlushConsoleInputBuffer (GetStdHandle (STD_INPUT_HANDLE)); getch(); } @@ -676,4 +705,3 @@ int main(int argc, char **argv) return ret; } - diff --git a/rtgui/multilangmgr.cc b/rtgui/multilangmgr.cc index d8a619292..7cc79d19a 100644 --- a/rtgui/multilangmgr.cc +++ b/rtgui/multilangmgr.cc @@ -19,7 +19,6 @@ #include "multilangmgr.h" #include -#include #ifdef WIN32 #include @@ -107,57 +106,52 @@ MultiLangMgr::MultiLangMgr () { } -MultiLangMgr::MultiLangMgr (const Glib::ustring& fname, MultiLangMgr* fallbackMgr) +void MultiLangMgr::load (const std::vector &fnames) { - load (fname, fallbackMgr); -} + translations.clear(); -bool MultiLangMgr::load (const Glib::ustring& fname, MultiLangMgr* fallbackMgr) -{ - this->fallbackMgr.reset (fallbackMgr); - - std::ifstream file (fname.c_str ()); - if (!file.is_open ()) { - return false; - } - - std::map translations; - std::string entry, key, value; - - while (std::getline (file, entry)) { - - if (entry.empty () || entry.front () == '#') { + for (const auto& fname : fnames) { + if(fname.empty()) { continue; } - std::istringstream line (entry); - - if (!std::getline (line, key, ';') || !std::getline (line, value)) { + std::ifstream file(fname.c_str()); + if (!file.is_open()) { continue; } - static const std::regex newline ("\\\\n"); - value = std::regex_replace (value, newline, "\n"); + std::string entry; + auto hint = translations.begin(); + while (std::getline(file, entry)) { - translations.emplace (key, value); + if (entry.empty() || entry.front() == '#' || entry.front() == '!') { + continue; + } + + std::string key, value; + + std::istringstream line(entry); + + if(std::getline(line, key, ';') && translations.find(key) == translations.end() && std::getline(line, value)) { + size_t pos = 0; + while((pos = value.find("\\n", pos)) != std::string::npos) { + value.replace(pos, 2, "\n"); + pos++; + } + hint = translations.emplace_hint(hint, key, value); + } + } } - - this->translations.swap (translations); - return true; } Glib::ustring MultiLangMgr::getStr (const std::string& key) const { - const auto iterator = translations.find (key); + const auto iterator = translations.find(key); - if (iterator != translations.end ()) { + if (iterator != translations.end()) { return iterator->second; } - if (fallbackMgr) { - return fallbackMgr->getStr (key); - } - return key; } diff --git a/rtgui/multilangmgr.h b/rtgui/multilangmgr.h index be46b1197..d439307e3 100644 --- a/rtgui/multilangmgr.h +++ b/rtgui/multilangmgr.h @@ -20,8 +20,8 @@ #define _MULTILANGMGR_ #include -#include #include +#include #include @@ -29,22 +29,14 @@ class MultiLangMgr { public: MultiLangMgr (); - MultiLangMgr (const Glib::ustring& fname, MultiLangMgr* fallbackMgr = nullptr); -public: - bool load (const Glib::ustring& fname, MultiLangMgr* fallbackMgr = nullptr); - -public: - Glib::ustring getStr (const std::string& key) const; - -public: - static bool isOSLanguageDetectSupported (); - static Glib::ustring getOSUserLanguage (); + void load(const std::vector &fnames); + Glib::ustring getStr(const std::string& key) const; + static bool isOSLanguageDetectSupported(); + static Glib::ustring getOSUserLanguage(); private: std::map translations; - std::unique_ptr fallbackMgr; - }; extern MultiLangMgr langMgr; diff --git a/rtgui/options.cc b/rtgui/options.cc index 7293a3a63..d1b91c3ac 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -309,7 +309,6 @@ void Options::setDefaults () saveFormat.format = "jpg"; saveFormat.jpegQuality = 92; saveFormat.jpegSubSamp = 2; - saveFormat.pngCompression = 6; saveFormat.pngBits = 8; saveFormat.tiffBits = 16; saveFormat.tiffUncompressed = true; @@ -318,7 +317,6 @@ void Options::setDefaults () saveFormatBatch.format = "jpg"; saveFormatBatch.jpegQuality = 92; saveFormatBatch.jpegSubSamp = 2; - saveFormatBatch.pngCompression = 6; saveFormatBatch.pngBits = 8; saveFormatBatch.tiffBits = 16; saveFormatBatch.tiffUncompressed = true; @@ -354,6 +352,7 @@ void Options::setDefaults () CPFontFamily = "default"; CPFontSize = 8; lastScale = 5; + lastShowAllExif = false; panAccelFactor = 5; rememberZoomAndPan = true; lastCropSize = 1; @@ -405,6 +404,7 @@ void Options::setDefaults () editorToSendTo = 1; favoriteDirs.clear(); tpOpen.clear (); + autoSaveTpOpen = true; //crvOpen.clear (); parseExtensions.clear (); parseExtensionsEnabled.clear (); @@ -509,120 +509,8 @@ void Options::setDefaults () sndLngEditProcDone = "window-attention"; #endif - // Reminder: 0 = SET mode, 1 = ADD mode - baBehav = { - 1, // ADDSET_TC_EXPCOMP - 1, // ADDSET_TC_BRIGHTNESS - 1, // ADDSET_TC_BLACKLEVEL - 1, // ADDSET_TC_CONTRAST - 1, // ADDSET_SH_HIGHLIGHTS - 1, // ADDSET_SH_SHADOWS - 1, // ADDSET_SH_LOCALCONTRAST - 1, // ADDSET_LC_BRIGHTNESS - 1, // ADDSET_LC_CONTRAST - 1, // ADDSET_SHARP_AMOUNT - 1, // ADDSET_WB_TEMPERATURE - 1, // ADDSET_WB_GREEN - 1, // ADDSET_ROTATE_DEGREE - 1, // ADDSET_DIST_AMOUNT - 1, // ADDSET_PERSPECTIVE - 1, // ADDSET_CA - 1, // ADDSET_VIGN_AMOUNT - 1, // ADDSET_VIGN_RADIUS - 1, // ADDSET_VIGN_STRENGTH - 1, // ADDSET_VIGN_CENTER - 1, // ADDSET_LC_CHROMATICITY - 1, // ADDSET_TC_SATURATION - 1, // ADDSET_TC_HLCOMPAMOUNT - 1, // ADDSET_TC_HLCOMPTHRESH - 1, // ADDSET_TC_SHCOMP - 1, // ADDSET_DIRPYREQ - 1, // ADDSET_DIRPYRDN_LUMA - 1, // ADDSET_DIRPYRDN_LUDET - 1, // ADDSET_DIRPYRDN_CHROMA - 1, // ADDSET_DIRPYRDN_CHROMARED - 1, // ADDSET_DIRPYRDN_CHROMABLUE - 1, // ADDSET_DIRPYRDN_GAMMA - 1, // ADDSET_CHMIXER - 1, // ADDSET_PREPROCESS_GREENEQUIL - 1, // ADDSET_PREPROCESS_LINEDENOISE - 1, // ADDSET_RAWCACORR - 1, // ADDSET_RAWEXPOS_LINEAR - 1, // ADDSET_RAWEXPOS_PRESER - 1, // ADDSET_RAWEXPOS_BLACKS - 1, // ADDSET_SHARPENEDGE_AMOUNT - 1, // ADDSET_SHARPENMICRO_AMOUNT - 1, // ADDSET_SHARPENEDGE_PASS - 1, // ADDSET_SHARPENMICRO_UNIFORMITY - 1, // ADDSET_VIBRANCE_PASTELS - 1, // ADDSET_VIBRANCE_SATURATED - 1, // ADDSET_FREE_OUPUT_GAMMA - 1, // ADDSET_FREE_OUTPUT_SLOPE - 1, // ADDSET_CAT_DEGREE - 1, // ADDSET_CAT_ADAPSCEN - 1, // ADDSET_CAT_ADAPLUM - 1, // ADDSET_CAT_LIGHT - 1, // ADDSET_CAT_RSTPRO - 1, // ADDSET_CAT_BADPIX - 1, // ADDSET_CAT_JLIGHT - 1, // ADDSET_CAT_CHROMA - 1, // ADDSET_CAT_CONTRAST - 1, // ADDSET_CAT_CHROMA_S - 1, // ADDSET_CAT_CHROMA_M - 1, // ADDSET_CAT_HUE - 1, // ADDSET_CAT_BADPIX - 1, // ADDSET_WB_EQUAL - 1, // ADDSET_GRADIENT_DEGREE - 1, // ADDSET_GRADIENT_FEATHER - 1, // ADDSET_GRADIENT_STRENGTH - 1, // ADDSET_GRADIENT_CENTER - 1, // ADDSET_PCVIGNETTE_STRENGTH - 1, // ADDSET_PCVIGNETTE_FEATHER - 1, // ADDSET_PCVIGNETTE_ROUNDNESS - 1, // ADDSET_BLACKWHITE_HUES - 1, // ADDSET_BLACKWHITE_GAMMA - 1, // ADDSET_DIRPYREQ_THRESHOLD - 1, // ADDSET_DIRPYREQ_SKINPROTECT - 1, // ADDSET_COLORTONING_SPLIT - 1, // ADDSET_COLORTONING_SATTHRESHOLD - 1, // ADDSET_COLORTONING_SATOPACITY - 1, // ADDSET_COLORTONING_BALANCE - 1, // ADDSET_COLORTONING_STRENGTH - 1, // ADDSET_DIRPYRDN_PASSES - 1, // ADDSET_RAWFFCLIPCONTROL - 1, // ADDSET_FILMSIMULATION_STRENGTH - 1, // ADDSET_WA - 1, // ADDSET_WA_SKINPROTECT - 1, // ADDSET_WA_THRESHOLD2 - 1, // ADDSET_WA_THRR - 1, // ADDSET_WA_THRRH - 1, // ADDSET_WA_THRESHOLD - 1, // ADDSET_WA_THRESHOLD2 - 1, // ADDSET_WA_CHRO - 1, // ADDSET_WA_CHROMA - 1, // ADDSET_WA_CONTRAST - 1, // ADDSET_WA_RESCON - 1, // ADDSET_WA_RESCONH - 1, // ADDSET_WA_RESCHRO - 1, // ADDSET_WA_SKYPROTECT - 1, // ADDSET_WA_EDGRAD - 1, // ADDSET_WA_EDGVAL - 1, // ADDSET_WA_STRENGTH - 1, // ADDSET_WA_EDGEDETECT - 1, // ADDSET_WA_EDGEDETECTTHR - 1, // ADDSET_WA_EDGEDETECTTHR2 - 1, // ADDSET_WA_TMRS - 1, // ADDSET_WA_GAMMA - 1, // ADDSET_RETI_STR - 1, // ADDSET_RETI_NEIGH - 1, // ADDSET_RETI_LIMD - 1, // ADDSET_RETI_GAIN - 1, // ADDSET_RETI_OFFS - 1, // ADDSET_RETI_VART - 1, // ADDSET_RETI_GAM - 1, // ADDSET_RETI_SLO - 1, // ADDSET_WB_TEMPBIAS - }; + // 0 = SET mode, 1 = ADD mode + baBehav.assign(ADDSET_PARAM_NUM, 0); rtSettings.darkFramesPath = ""; rtSettings.flatFieldsPath = ""; @@ -642,7 +530,7 @@ void Options::setDefaults () #endif // rtSettings.viewingdevice = 0; // rtSettings.viewingdevicegrey = 3; - // rtSettings.viewinggreySc = 1; + // rtSettings.viewinggreySc = 1; rtSettings.leveldnv = 2; rtSettings.leveldnti = 0; rtSettings.leveldnaut = 0; @@ -726,6 +614,7 @@ void Options::setDefaults () lastLensProfileDir = ""; gimpPluginShowInfoDialog = true; maxRecentFolders = 15; + rtSettings.lensfunDbDirectory = ""; // set also in main.cc and main-cli.cc } Options* Options::copyFrom (Options* other) @@ -744,14 +633,15 @@ void Options::filterOutParsedExtensions () } } -int Options::readFromFile (Glib::ustring fname) +void Options::readFromFile (Glib::ustring fname) { setlocale (LC_NUMERIC, "C"); // to set decimal point to "." Glib::KeyFile keyFile; if ( !Glib::file_test (fname, Glib::FILE_TEST_EXISTS)) { - return 1; + Glib::ustring msg = Glib::ustring::compose ("Options file %1 does not exist", fname); + throw Error (msg); } try { @@ -898,10 +788,6 @@ int Options::readFromFile (Glib::ustring fname) saveFormat.jpegSubSamp = keyFile.get_integer ("Output", "JpegSubSamp"); } - if (keyFile.has_key ("Output", "PngCompression")) { - saveFormat.pngCompression = keyFile.get_integer ("Output", "PngCompression"); - } - if (keyFile.has_key ("Output", "PngBps")) { saveFormat.pngBits = keyFile.get_integer ("Output", "PngBps"); } @@ -931,10 +817,6 @@ int Options::readFromFile (Glib::ustring fname) saveFormatBatch.jpegSubSamp = keyFile.get_integer ("Output", "JpegSubSampBatch"); } - if (keyFile.has_key ("Output", "PngCompressionBatch")) { - saveFormatBatch.pngCompression = keyFile.get_integer ("Output", "PngCompressionBatch"); - } - if (keyFile.has_key ("Output", "PngBpsBatch")) { saveFormatBatch.pngBits = keyFile.get_integer ("Output", "PngBpsBatch"); } @@ -1387,6 +1269,10 @@ int Options::readFromFile (Glib::ustring fname) lastScale = keyFile.get_integer ("GUI", "LastPreviewScale"); } + if (keyFile.has_key ("GUI", "LastShowAllExif")) { + lastShowAllExif = keyFile.get_boolean ("GUI", "LastShowAllExif"); + } + if (keyFile.has_key ("GUI", "PanAccelFactor")) { panAccelFactor = keyFile.get_integer ("GUI", "PanAccelFactor"); } @@ -1435,6 +1321,10 @@ int Options::readFromFile (Glib::ustring fname) tpOpen = keyFile.get_integer_list ("GUI", "ToolPanelsExpanded"); } + if (keyFile.has_key ("GUI", "ToolPanelsExpandedAutoSave")) { + autoSaveTpOpen = keyFile.get_boolean ("GUI", "ToolPanelsExpandedAutoSave"); + } + if (keyFile.has_key ("GUI", "MultiDisplayMode")) { multiDisplayMode = keyFile.get_integer ("GUI", "MultiDisplayMode"); } @@ -1557,11 +1447,11 @@ int Options::readFromFile (Glib::ustring fname) rtSettings.viewingdevicegrey = keyFile.get_integer ("Color Management", "grey"); } */ -/* - if (keyFile.has_key ("Color Management", "greySc")) { - rtSettings.viewinggreySc = keyFile.get_integer ("Color Management", "greySc"); - } -*/ + /* + if (keyFile.has_key ("Color Management", "greySc")) { + rtSettings.viewinggreySc = keyFile.get_integer ("Color Management", "greySc"); + } + */ if (keyFile.has_key ("Color Management", "CBDLArtif")) { rtSettings.artifact_cbdl = keyFile.get_double ("Color Management", "CBDLArtif"); } @@ -1862,25 +1752,36 @@ int Options::readFromFile (Glib::ustring fname) } } + if (keyFile.has_group ("Lensfun")) { + if (keyFile.has_key ("Lensfun", "DBDirectory")) { + rtSettings.lensfunDbDirectory = keyFile.get_string ("Lensfun", "DBDirectory"); + } + } + // -------------------------------------------------------------------------------------------------------- filterOutParsedExtensions (); - return 0; + return; } } catch (Glib::Error &err) { + Glib::ustring msg = Glib::ustring::compose ("Options::readFromFile / Error code %1 while reading values from \"%2\":\n%3", err.code(), fname, err.what()); + if (options.rtSettings.verbose) { - printf ("Options::readFromFile / Error code %d while reading values from \"%s\":\n%s\n", err.code(), fname.c_str(), err.what().c_str()); + printf ("%s\n", msg.c_str()); } + + throw Error (msg); } catch (...) { + Glib::ustring msg = Glib::ustring::compose ("Options::readFromFile / Unknown exception while trying to load \"%1\"!", fname); + if (options.rtSettings.verbose) { - printf ("Options::readFromFile / Unknown exception while trying to load \"%s\"!\n", fname.c_str()); + printf ("%s\n", msg.c_str()); } + + throw Error (msg); } - - return 1; - } bool Options::safeDirGet (const Glib::KeyFile& keyFile, const Glib::ustring& section, @@ -1898,7 +1799,7 @@ bool Options::safeDirGet (const Glib::KeyFile& keyFile, const Glib::ustring& sec return false; } -int Options::saveToFile (Glib::ustring fname) +void Options::saveToFile (Glib::ustring fname) { Glib::ustring keyData; @@ -2016,7 +1917,6 @@ int Options::saveToFile (Glib::ustring fname) keyFile.set_string ("Output", "Format", saveFormat.format); keyFile.set_integer ("Output", "JpegQuality", saveFormat.jpegQuality); keyFile.set_integer ("Output", "JpegSubSamp", saveFormat.jpegSubSamp); - keyFile.set_integer ("Output", "PngCompression", saveFormat.pngCompression); keyFile.set_integer ("Output", "PngBps", saveFormat.pngBits); keyFile.set_integer ("Output", "TiffBps", saveFormat.tiffBits); keyFile.set_boolean ("Output", "TiffUncompressed", saveFormat.tiffUncompressed); @@ -2025,7 +1925,6 @@ int Options::saveToFile (Glib::ustring fname) keyFile.set_string ("Output", "FormatBatch", saveFormatBatch.format); keyFile.set_integer ("Output", "JpegQualityBatch", saveFormatBatch.jpegQuality); keyFile.set_integer ("Output", "JpegSubSampBatch", saveFormatBatch.jpegSubSamp); - keyFile.set_integer ("Output", "PngCompressionBatch", saveFormatBatch.pngCompression); keyFile.set_integer ("Output", "PngBpsBatch", saveFormatBatch.pngBits); keyFile.set_integer ("Output", "TiffBpsBatch", saveFormatBatch.tiffBits); keyFile.set_boolean ("Output", "TiffUncompressedBatch", saveFormatBatch.tiffUncompressed); @@ -2087,6 +1986,7 @@ int Options::saveToFile (Glib::ustring fname) keyFile.set_string ("GUI", "CPFontFamily", CPFontFamily); keyFile.set_integer ("GUI", "CPFontSize", CPFontSize); keyFile.set_integer ("GUI", "LastPreviewScale", lastScale); + keyFile.set_boolean ("GUI", "LastShowAllExif", lastShowAllExif); keyFile.set_integer ("GUI", "PanAccelFactor", panAccelFactor); keyFile.set_boolean ("GUI", "RememberZoomAndPan", rememberZoomAndPan); keyFile.set_integer ("GUI", "LastCropSize", lastCropSize); @@ -2100,6 +2000,7 @@ int Options::saveToFile (Glib::ustring fname) keyFile.set_boolean ("GUI", "ProcessingQueueEnbled", procQueueEnabled); Glib::ArrayHandle tpopen = tpOpen; keyFile.set_integer_list ("GUI", "ToolPanelsExpanded", tpopen); + keyFile.set_boolean ("GUI", "ToolPanelsExpandedAutoSave", autoSaveTpOpen); keyFile.set_integer ("GUI", "MultiDisplayMode", multiDisplayMode); keyFile.set_double_list ("GUI", "CutOverlayBrush", cutOverlayBrush); keyFile.set_double_list ("GUI", "NavGuideBrush", navGuideBrush); @@ -2227,33 +2128,27 @@ int Options::saveToFile (Glib::ustring fname) keyFile.set_string ("Dialogs", "LastLensProfileDir", lastLensProfileDir); keyFile.set_boolean ("Dialogs", "GimpPluginShowInfoDialog", gimpPluginShowInfoDialog); + keyFile.set_string ("Lensfun", "DBDirectory", rtSettings.lensfunDbDirectory); + keyData = keyFile.to_data (); - } catch (Glib::KeyFileError&) {} - - if (keyData.empty ()) { - return 1; + } catch (Glib::KeyFileError &e) { + throw Error (e.what()); } FILE *f = g_fopen (fname.c_str (), "wt"); if (f == nullptr) { std::cout << "Warning! Unable to save your preferences to: " << fname << std::endl; -#ifndef RAWTHERAPEE_CLI Glib::ustring msg_ = Glib::ustring::compose (M ("MAIN_MSG_WRITEFAILED"), fname.c_str()); - //writeFailed (getToplevelWindow (this), msg_); - Gtk::MessageDialog msgd (msg_, true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_CLOSE, true); - msgd.run (); -#endif - return 1; + throw Error (msg_); } else { fprintf (f, "%s", keyData.c_str ()); fclose (f); - return 0; } } -bool Options::load (bool lightweight) +void Options::load (bool lightweight) { // Find the application data path @@ -2267,7 +2162,8 @@ bool Options::load (bool lightweight) rtdir = Glib::ustring (path); if (!Glib::path_is_absolute (rtdir)) { - return false; + Glib::ustring msg = Glib::ustring::compose ("Settings path %1 is not absolute", rtdir); + throw Error (msg); } } else { #ifdef WIN32 @@ -2292,7 +2188,11 @@ bool Options::load (bool lightweight) cacheBaseDir = Glib::build_filename (argv0, "cache"); // Read the global option file (the one located in the application's base folder) - options.readFromFile (Glib::build_filename (argv0, "options")); + try { + options.readFromFile (Glib::build_filename (argv0, "options")); + } catch (Options::Error &) { + // ignore errors here + } // Modify the path of the cache folder to the one provided in RT_CACHE environment variable path = g_getenv ("RT_CACHE"); @@ -2301,7 +2201,8 @@ bool Options::load (bool lightweight) cacheBaseDir = Glib::ustring (path); if (!Glib::path_is_absolute (cacheBaseDir)) { - return false; + Glib::ustring msg = Glib::ustring::compose ("Cache base dir %1 is not absolute", cacheBaseDir); + throw Error (msg); } } // No environment variable provided, so falling back to the multi user mode, is enabled @@ -2317,12 +2218,14 @@ bool Options::load (bool lightweight) if (options.multiUser) { // Read the user option file (the one located somewhere in the user's home folder) // Those values supersets those of the global option file - int r = options.readFromFile (Glib::build_filename (rtdir, "options")); - - // If the local option file does not exist or is broken, and the local cache folder does not exist, recreate it - if (r && !g_mkdir_with_parents (rtdir.c_str (), 511)) { - // Save the option file - options.saveToFile (Glib::build_filename (rtdir, "options")); + try { + options.readFromFile (Glib::build_filename (rtdir, "options")); + } catch (Options::Error &) { + // If the local option file does not exist or is broken, and the local cache folder does not exist, recreate it + if (!g_mkdir_with_parents (rtdir.c_str (), 511)) { + // Save the option file + options.saveToFile (Glib::build_filename (rtdir, "options")); + } } #ifdef __APPLE__ @@ -2412,11 +2315,9 @@ bool Options::load (bool lightweight) } } - langMgr.load (localeTranslation, new MultiLangMgr (languageTranslation, new MultiLangMgr (defaultTranslation))); + langMgr.load ({localeTranslation, languageTranslation, defaultTranslation}); rtengine::init (&options.rtSettings, argv0, rtdir, !lightweight); - - return true; } void Options::save () diff --git a/rtgui/options.h b/rtgui/options.h index 13025ee7c..947d3b615 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -21,6 +21,7 @@ #include #include "../rtengine/rtengine.h" +#include #define STARTUPDIR_CURRENT 0 #define STARTUPDIR_HOME 1 @@ -42,23 +43,20 @@ // Special name for the Dynamic profile #define DEFPROFILE_DYNAMIC "Dynamic" -struct SaveFormat -{ +struct SaveFormat { SaveFormat() : - format("jpg"), - pngBits(8), - pngCompression(6), - jpegQuality(90), - jpegSubSamp(2), - tiffBits(8), - tiffUncompressed(true), - saveParams(true) + format ("jpg"), + pngBits (8), + jpegQuality (90), + jpegSubSamp (2), + tiffBits (8), + tiffUncompressed (true), + saveParams (true) { } Glib::ustring format; int pngBits; - int pngCompression; int jpegQuality; int jpegSubSamp; // 1=best compression, 3=best quality int tiffBits; @@ -73,14 +71,31 @@ enum prevdemo_t {PD_Sidecar = 1, PD_Fast = 0}; class Options { +public: + class Error: public std::exception + { + public: + Error (const Glib::ustring &msg): msg_ (msg) {} + const char *what() const throw() + { + return msg_.c_str(); + } + const Glib::ustring &get_msg() const throw() + { + return msg_; + } + + private: + Glib::ustring msg_; + }; private: bool defProfRawMissing; bool defProfImgMissing; Glib::ustring userProfilePath; Glib::ustring globalProfilePath; - bool checkProfilePath(Glib::ustring &path); - bool checkDirPath(Glib::ustring &path, Glib::ustring errString); + bool checkProfilePath (Glib::ustring &path); + bool checkDirPath (Glib::ustring &path, Glib::ustring errString); void updatePaths(); int getString (const char* src, char* dst); void error (int line); @@ -95,8 +110,8 @@ private: * @param destination destination variable to store to * @return @c true if @p destination was changed */ - bool safeDirGet(const Glib::KeyFile& keyFile, const Glib::ustring& section, - const Glib::ustring& entryName, Glib::ustring& destination); + bool safeDirGet (const Glib::KeyFile& keyFile, const Glib::ustring& section, + const Glib::ustring& entryName, Glib::ustring& destination); public: @@ -151,6 +166,7 @@ public: int dirBrowserHeight; int preferencesWidth; int preferencesHeight; + bool lastShowAllExif; int lastScale; int panAccelFactor; int lastCropSize; @@ -206,6 +222,7 @@ public: std::vector parseExtensionsEnabled; // List of bool to retain extension or not std::vector parsedExtensions; // List containing all retained extensions (lowercase) std::vector tpOpen; + bool autoSaveTpOpen; //std::vector crvOpen; std::vector baBehav; rtengine::Settings rtSettings; @@ -326,10 +343,10 @@ public: Options* copyFrom (Options* other); void filterOutParsedExtensions (); void setDefaults (); - int readFromFile (Glib::ustring fname); - int saveToFile (Glib::ustring fname); - static bool load (bool lightweight = false); - static void save (); + void readFromFile (Glib::ustring fname); + void saveToFile (Glib::ustring fname); + static void load (bool lightweight = false); + static void save(); // if multiUser=false, send back the global profile path Glib::ustring getPreferredProfilePath(); @@ -341,10 +358,10 @@ public: { return globalProfilePath; } - Glib::ustring findProfilePath(Glib::ustring &profName); + Glib::ustring findProfilePath (Glib::ustring &profName); bool is_parse_extention (Glib::ustring fname); bool has_retained_extention (Glib::ustring fname); - bool is_extention_enabled(Glib::ustring ext); + bool is_extention_enabled (Glib::ustring ext); bool is_defProfRawMissing() { return defProfRawMissing; @@ -353,11 +370,11 @@ public: { return defProfImgMissing; } - void setDefProfRawMissing(bool value) + void setDefProfRawMissing (bool value) { defProfRawMissing = value; } - void setDefProfImgMissing(bool value) + void setDefProfImgMissing (bool value) { defProfImgMissing = value; } diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 01ecfbe97..b7851c2c1 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -264,6 +264,9 @@ void ParamsEdited::set (bool v) epd.edgeStopping = v; epd.scale = v; epd.reweightingIterates = v; + fattal.enabled = v; + fattal.threshold = v; + fattal.amount = v; sh.enabled = v; sh.hq = v; sh.highlights = v; @@ -287,10 +290,16 @@ void ParamsEdited::set (bool v) commonTrans.autofill = v; rotate.degree = v; distortion.amount = v; + lensProf.lcMode = v; lensProf.lcpFile = v; lensProf.useDist = v; lensProf.useVign = v; lensProf.useCA = v; + lensProf.useLensfun = v; + lensProf.lfAutoMatch = v; + lensProf.lfCameraMake = v; + lensProf.lfCameraModel = v; + lensProf.lfLens = v; perspective.horizontal = v; perspective.vertical = v; gradient.enabled = v; @@ -802,6 +811,10 @@ void ParamsEdited::initFrom (const std::vector epd.scale = epd.scale && p.epd.scale == other.epd.scale; epd.reweightingIterates = epd.reweightingIterates && p.epd.reweightingIterates == other.epd.reweightingIterates; + fattal.enabled = fattal.enabled && p.fattal.enabled == other.fattal.enabled; + fattal.threshold = fattal.threshold && p.fattal.threshold == other.fattal.threshold; + fattal.amount = fattal.amount && p.fattal.amount == other.fattal.amount; + sh.enabled = sh.enabled && p.sh.enabled == other.sh.enabled; sh.hq = sh.hq && p.sh.hq == other.sh.hq; sh.highlights = sh.highlights && p.sh.highlights == other.sh.highlights; @@ -825,10 +838,16 @@ void ParamsEdited::initFrom (const std::vector commonTrans.autofill = commonTrans.autofill && p.commonTrans.autofill == other.commonTrans.autofill; rotate.degree = rotate.degree && p.rotate.degree == other.rotate.degree; distortion.amount = distortion.amount && p.distortion.amount == other.distortion.amount; + lensProf.lcMode = lensProf.lcMode && p.lensProf.lcMode == other.lensProf.lcMode; lensProf.lcpFile = lensProf.lcpFile && p.lensProf.lcpFile == other.lensProf.lcpFile; lensProf.useDist = lensProf.useDist && p.lensProf.useDist == other.lensProf.useDist; lensProf.useVign = lensProf.useVign && p.lensProf.useVign == other.lensProf.useVign; lensProf.useCA = lensProf.useCA && p.lensProf.useCA == other.lensProf.useCA; + lensProf.useLensfun = lensProf.useLensfun && p.lensProf.useLensfun() == other.lensProf.useLensfun(); + lensProf.lfAutoMatch = lensProf.lfAutoMatch && p.lensProf.lfAutoMatch() == other.lensProf.lfAutoMatch(); + lensProf.lfCameraMake = lensProf.lfCameraMake && p.lensProf.lfCameraMake == other.lensProf.lfCameraMake; + lensProf.lfCameraModel = lensProf.lfCameraModel && p.lensProf.lfCameraModel == other.lensProf.lfCameraModel; + lensProf.lfLens = lensProf.lfLens && p.lensProf.lfLens == other.lensProf.lfLens; perspective.horizontal = perspective.horizontal && p.perspective.horizontal == other.perspective.horizontal; perspective.vertical = perspective.vertical && p.perspective.vertical == other.perspective.vertical; gradient.enabled = gradient.enabled && p.gradient.enabled == other.gradient.enabled; @@ -1324,7 +1343,7 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten } if (labCurve.contrast) { - toEdit.labCurve.contrast = dontforceSet && options.baBehav[ADDSET_LC_CONTRAST] ? toEdit.labCurve.contrast + mods.labCurve.contrast : mods.labCurve.contrast; + toEdit.labCurve.contrast = dontforceSet && options.baBehav[ADDSET_LC_CONTRAST] ? toEdit.labCurve.contrast + mods.labCurve.contrast : mods.labCurve.contrast; } if (labCurve.chromaticity) { @@ -1332,15 +1351,15 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten } if (labCurve.avoidcolorshift) { - toEdit.labCurve.avoidcolorshift = mods.labCurve.avoidcolorshift; + toEdit.labCurve.avoidcolorshift = mods.labCurve.avoidcolorshift; } if (labCurve.rstprotection) { - toEdit.labCurve.rstprotection = mods.labCurve.rstprotection; + toEdit.labCurve.rstprotection = mods.labCurve.rstprotection; } if (labCurve.lcredsk) { - toEdit.labCurve.lcredsk = mods.labCurve.lcredsk; + toEdit.labCurve.lcredsk = mods.labCurve.lcredsk; } if (rgbCurves.lumamode) { @@ -1360,11 +1379,11 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten } if (colorToning.enabled) { - toEdit.colorToning.enabled = mods.colorToning.enabled; + toEdit.colorToning.enabled = mods.colorToning.enabled; } if (colorToning.twocolor) { - toEdit.colorToning.twocolor = mods.colorToning.twocolor; + toEdit.colorToning.twocolor = mods.colorToning.twocolor; } if (colorToning.opacityCurve) { @@ -1388,19 +1407,19 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten } if (colorToning.autosat) { - toEdit.colorToning.autosat = mods.colorToning.autosat; + toEdit.colorToning.autosat = mods.colorToning.autosat; } if (colorToning.saturatedopacity) { - toEdit.colorToning.saturatedOpacity = dontforceSet && options.baBehav[ADDSET_COLORTONING_SATOPACITY] ? toEdit.colorToning.saturatedOpacity + mods.colorToning.saturatedOpacity : mods.colorToning.saturatedOpacity; + toEdit.colorToning.saturatedOpacity = dontforceSet && options.baBehav[ADDSET_COLORTONING_SATOPACITY] ? toEdit.colorToning.saturatedOpacity + mods.colorToning.saturatedOpacity : mods.colorToning.saturatedOpacity; } if (colorToning.strength) { - toEdit.colorToning.strength = dontforceSet && options.baBehav[ADDSET_COLORTONING_STRENGTH] ? toEdit.colorToning.strength + mods.colorToning.strength : mods.colorToning.strength; + toEdit.colorToning.strength = dontforceSet && options.baBehav[ADDSET_COLORTONING_STRENGTH] ? toEdit.colorToning.strength + mods.colorToning.strength : mods.colorToning.strength; } if (colorToning.shadowsColSat) { - toEdit.colorToning.shadowsColSat = mods.colorToning.shadowsColSat; + toEdit.colorToning.shadowsColSat = mods.colorToning.shadowsColSat; } if (colorToning.hlColSat) { @@ -1508,7 +1527,7 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten } if (sharpening.radius) { - toEdit.sharpening.radius = mods.sharpening.radius; + toEdit.sharpening.radius = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.sharpening.radius + mods.sharpening.radius : mods.sharpening.radius; } if (sharpening.amount) { @@ -1524,19 +1543,19 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten } if (sharpening.edges_radius) { - toEdit.sharpening.edges_radius = mods.sharpening.edges_radius; + toEdit.sharpening.edges_radius = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.sharpening.edges_radius + mods.sharpening.edges_radius: mods.sharpening.edges_radius; } if (sharpening.edges_tolerance) { - toEdit.sharpening.edges_tolerance = mods.sharpening.edges_tolerance; + toEdit.sharpening.edges_tolerance = dontforceSet && options.baBehav[ADDSET_SHARP_EDGETOL] ? toEdit.sharpening.edges_tolerance + mods.sharpening.edges_tolerance : mods.sharpening.edges_tolerance; } if (sharpening.halocontrol) { - toEdit.sharpening.halocontrol = mods.sharpening.halocontrol; + toEdit.sharpening.halocontrol = mods.sharpening.halocontrol; } if (sharpening.halocontrol_amount) { - toEdit.sharpening.halocontrol_amount = mods.sharpening.halocontrol_amount; + toEdit.sharpening.halocontrol_amount = dontforceSet && options.baBehav[ADDSET_SHARP_HALOCTRL] ? toEdit.sharpening.halocontrol_amount + mods.sharpening.halocontrol_amount : mods.sharpening.halocontrol_amount; } if (sharpening.method) { @@ -1544,19 +1563,19 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten } if (sharpening.deconvamount) { - toEdit.sharpening.deconvamount = dontforceSet && options.baBehav[ADDSET_SHARP_AMOUNT] ? toEdit.sharpening.deconvamount + mods.sharpening.deconvamount : mods.sharpening.deconvamount; + toEdit.sharpening.deconvamount = dontforceSet && options.baBehav[ADDSET_SHARP_AMOUNT] ? toEdit.sharpening.deconvamount + mods.sharpening.deconvamount : mods.sharpening.deconvamount; } if (sharpening.deconvradius) { - toEdit.sharpening.deconvradius = mods.sharpening.deconvradius; + toEdit.sharpening.deconvradius = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.sharpening.deconvradius + mods.sharpening.deconvradius : mods.sharpening.deconvradius; } if (sharpening.deconviter) { - toEdit.sharpening.deconviter = mods.sharpening.deconviter; + toEdit.sharpening.deconviter = dontforceSet && options.baBehav[ADDSET_SHARP_ITER] ? toEdit.sharpening.deconviter + mods.sharpening.deconviter : mods.sharpening.deconviter; } if (sharpening.deconvdamping) { - toEdit.sharpening.deconvdamping = mods.sharpening.deconvdamping; + toEdit.sharpening.deconvdamping = dontforceSet && options.baBehav[ADDSET_SHARP_DAMPING] ? toEdit.sharpening.deconvdamping + mods.sharpening.deconvdamping : mods.sharpening.deconvdamping; } if (prsharpening.enabled) { @@ -1564,7 +1583,7 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten } if (prsharpening.radius) { - toEdit.prsharpening.radius = mods.prsharpening.radius; + toEdit.prsharpening.radius = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.prsharpening.radius + mods.prsharpening.radius : mods.prsharpening.radius; } if (prsharpening.amount) { @@ -1580,11 +1599,11 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten } if (prsharpening.edges_radius) { - toEdit.prsharpening.edges_radius = mods.prsharpening.edges_radius; + toEdit.prsharpening.edges_radius = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.prsharpening.edges_radius + mods.prsharpening.edges_radius : mods.prsharpening.edges_radius; } if (prsharpening.edges_tolerance) { - toEdit.prsharpening.edges_tolerance = mods.prsharpening.edges_tolerance; + toEdit.prsharpening.edges_tolerance = dontforceSet && options.baBehav[ADDSET_SHARP_EDGETOL] ? toEdit.prsharpening.edges_tolerance + mods.prsharpening.edges_tolerance : mods.prsharpening.edges_tolerance; } if (prsharpening.halocontrol) { @@ -1592,7 +1611,7 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten } if (prsharpening.halocontrol_amount) { - toEdit.prsharpening.halocontrol_amount = mods.prsharpening.halocontrol_amount; + toEdit.prsharpening.halocontrol_amount = dontforceSet && options.baBehav[ADDSET_SHARP_HALOCTRL] ? toEdit.prsharpening.halocontrol_amount + mods.prsharpening.halocontrol_amount : mods.prsharpening.halocontrol_amount; } if (prsharpening.method) { @@ -1604,15 +1623,15 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten } if (prsharpening.deconvradius) { - toEdit.prsharpening.deconvradius = mods.prsharpening.deconvradius; + toEdit.prsharpening.deconvradius = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.prsharpening.deconvradius + mods.prsharpening.deconvradius : mods.prsharpening.deconvradius; } if (prsharpening.deconviter) { - toEdit.prsharpening.deconviter = mods.prsharpening.deconviter; + toEdit.prsharpening.deconviter = dontforceSet && options.baBehav[ADDSET_SHARP_ITER] ? toEdit.prsharpening.deconviter + mods.prsharpening.deconviter : mods.prsharpening.deconviter; } if (prsharpening.deconvdamping) { - toEdit.prsharpening.deconvdamping = mods.prsharpening.deconvdamping; + toEdit.prsharpening.deconvdamping = dontforceSet && options.baBehav[ADDSET_SHARP_DAMPING] ? toEdit.prsharpening.deconvdamping + mods.prsharpening.deconvdamping : mods.prsharpening.deconvdamping; } if (vibrance.enabled) { @@ -1752,7 +1771,7 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten } if (colorappearance.adapscen) { - toEdit.colorappearance.adapscen = mods.colorappearance.adapscen; + toEdit.colorappearance.adapscen = dontforceSet && options.baBehav[ADDSET_CAT_ADAPTSCENE] ? toEdit.colorappearance.adapscen + mods.colorappearance.adapscen : mods.colorappearance.adapscen; } if (colorappearance.autoybscen) { @@ -1966,6 +1985,16 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten toEdit.epd.reweightingIterates = mods.epd.reweightingIterates; } + if (fattal.enabled) { + toEdit.fattal.enabled = mods.fattal.enabled; + } + if (fattal.threshold) { + toEdit.fattal.threshold = mods.fattal.threshold; + } + if (fattal.amount) { + toEdit.fattal.amount = mods.fattal.amount; + } + if (sh.enabled) { toEdit.sh.enabled = mods.sh.enabled; } @@ -2058,6 +2087,10 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten toEdit.distortion.amount = dontforceSet && options.baBehav[ADDSET_DIST_AMOUNT] ? toEdit.distortion.amount + mods.distortion.amount : mods.distortion.amount; } + if (lensProf.lcMode) { + toEdit.lensProf.lcMode = mods.lensProf.lcMode; + } + if (lensProf.lcpFile) { toEdit.lensProf.lcpFile = mods.lensProf.lcpFile; } @@ -2074,6 +2107,18 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten toEdit.lensProf.useCA = mods.lensProf.useCA; } + if (lensProf.lfCameraMake) { + toEdit.lensProf.lfCameraMake = mods.lensProf.lfCameraMake; + } + + if (lensProf.lfCameraModel) { + toEdit.lensProf.lfCameraModel = mods.lensProf.lfCameraModel; + } + + if (lensProf.lfLens) { + toEdit.lensProf.lfLens = mods.lensProf.lfLens; + } + if (perspective.horizontal) { toEdit.perspective.horizontal = dontforceSet && options.baBehav[ADDSET_PERSPECTIVE] ? toEdit.perspective.horizontal + mods.perspective.horizontal : mods.perspective.horizontal; } @@ -2087,23 +2132,23 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten } if (gradient.degree) { - toEdit.gradient.degree = dontforceSet && options.baBehav[ADDSET_GRADIENT_DEGREE] ? toEdit.gradient.degree + mods.gradient.degree : mods.gradient.degree; + toEdit.gradient.degree = dontforceSet && options.baBehav[ADDSET_GRADIENT_DEGREE] ? toEdit.gradient.degree + mods.gradient.degree : mods.gradient.degree; } if (gradient.feather) { - toEdit.gradient.feather = mods.gradient.feather; + toEdit.gradient.feather = dontforceSet && options.baBehav[ADDSET_GRADIENT_FEATHER] ? toEdit.gradient.feather + mods.gradient.feather : mods.gradient.feather; } if (gradient.strength) { - toEdit.gradient.strength = mods.gradient.strength; + toEdit.gradient.strength = dontforceSet && options.baBehav[ADDSET_GRADIENT_STRENGTH] ? toEdit.gradient.strength + mods.gradient.strength : mods.gradient.strength; } if (gradient.centerX) { - toEdit.gradient.centerX = mods.gradient.centerX; + toEdit.gradient.centerX = dontforceSet && options.baBehav[ADDSET_GRADIENT_CENTER] ? toEdit.gradient.centerX + mods.gradient.centerX : mods.gradient.centerX; } if (gradient.centerY) { - toEdit.gradient.centerY = mods.gradient.centerY; + toEdit.gradient.centerY = dontforceSet && options.baBehav[ADDSET_GRADIENT_CENTER] ? toEdit.gradient.centerY + mods.gradient.centerY : mods.gradient.centerY; } if (pcvignette.enabled) { @@ -2111,15 +2156,15 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten } if (pcvignette.strength) { - toEdit.pcvignette.strength = mods.pcvignette.strength; + toEdit.pcvignette.strength = dontforceSet && options.baBehav[ADDSET_PCVIGNETTE_STRENGTH] ? toEdit.pcvignette.strength + mods.pcvignette.strength : mods.pcvignette.strength; } if (pcvignette.feather) { - toEdit.pcvignette.feather = mods.pcvignette.feather; + toEdit.pcvignette.feather = dontforceSet && options.baBehav[ADDSET_PCVIGNETTE_FEATHER] ? toEdit.pcvignette.feather + mods.pcvignette.feather : mods.pcvignette.feather; } if (pcvignette.roundness) { - toEdit.pcvignette.roundness = mods.pcvignette.roundness; + toEdit.pcvignette.roundness = dontforceSet && options.baBehav[ADDSET_PCVIGNETTE_ROUNDNESS] ? toEdit.pcvignette.roundness + mods.pcvignette.roundness : mods.pcvignette.roundness; } if (cacorrection.red) { @@ -2135,19 +2180,19 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten } if (vignetting.radius) { - toEdit.vignetting.radius = mods.vignetting.radius; + toEdit.vignetting.radius = dontforceSet && options.baBehav[ADDSET_VIGN_RADIUS] ? toEdit.vignetting.radius + mods.vignetting.radius : mods.vignetting.radius; } if (vignetting.strength) { - toEdit.vignetting.strength = mods.vignetting.strength; + toEdit.vignetting.strength = dontforceSet && options.baBehav[ADDSET_VIGN_STRENGTH] ? toEdit.vignetting.strength + mods.vignetting.strength : mods.vignetting.strength; } if (vignetting.centerX) { - toEdit.vignetting.centerX = mods.vignetting.centerX; + toEdit.vignetting.centerX = dontforceSet && options.baBehav[ADDSET_VIGN_CENTER] ? toEdit.vignetting.centerX + mods.vignetting.centerX : mods.vignetting.centerX; } if (vignetting.centerY) { - toEdit.vignetting.centerY = mods.vignetting.centerY; + toEdit.vignetting.centerY = dontforceSet && options.baBehav[ADDSET_VIGN_CENTER] ? toEdit.vignetting.centerY + mods.vignetting.centerY : mods.vignetting.centerY; } for (int i = 0; i < 3; i++) { @@ -2257,7 +2302,7 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten } if (resize.scale) { - toEdit.resize.scale = mods.resize.scale; + toEdit.resize.scale = dontforceSet && options.baBehav[ADDSET_RESIZE_SCALE] ? toEdit.resize.scale + mods.resize.scale : mods.resize.scale; } if (resize.appliesTo) { @@ -3037,7 +3082,7 @@ bool RAWParamsEdited::isUnchanged() const bool LensProfParamsEdited::isUnchanged() const { - return lcpFile; + return lcMode && lcpFile && useVign && lfLens; } bool RetinexParamsEdited::isUnchanged() const diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 4f0dc0029..904a7ec84 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -365,6 +365,14 @@ public: }; +class FattalToneMappingParamsEdited { +public: + bool enabled; + bool threshold; + bool amount; +}; + + class SHParamsEdited { @@ -428,6 +436,8 @@ class LensProfParamsEdited { public: bool lcpFile, useDist, useVign, useCA; + bool useLensfun, lfAutoMatch, lfCameraMake, lfCameraModel, lfLens; + bool lcMode; bool isUnchanged() const; }; @@ -805,6 +815,7 @@ public: DefringeParamsEdited defringe; DirPyrDenoiseParamsEdited dirpyrDenoise; EPDParamsEdited epd; + FattalToneMappingParamsEdited fattal; ImpulseDenoiseParamsEdited impulseDenoise; SHParamsEdited sh; CropParamsEdited crop; diff --git a/rtgui/partialpastedlg.cc b/rtgui/partialpastedlg.cc index ce26078fc..7d91e0172 100644 --- a/rtgui/partialpastedlg.cc +++ b/rtgui/partialpastedlg.cc @@ -51,6 +51,7 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren exposure = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_EXPOSURE"))); sh = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_SHADOWSHIGHLIGHTS"))); epd = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_EPD"))); + fattal = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_TM_FATTAL"))); retinex = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RETINEX"))); pcvignette = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_PCVIGNETTE"))); gradient = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_GRADIENT"))); @@ -143,6 +144,7 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren vboxes[0]->pack_start (*exposure, Gtk::PACK_SHRINK, 2); vboxes[0]->pack_start (*sh, Gtk::PACK_SHRINK, 2); vboxes[0]->pack_start (*epd, Gtk::PACK_SHRINK, 2); + vboxes[0]->pack_start (*fattal, Gtk::PACK_SHRINK, 2); vboxes[0]->pack_start (*retinex, Gtk::PACK_SHRINK, 2); vboxes[0]->pack_start (*pcvignette, Gtk::PACK_SHRINK, 2); vboxes[0]->pack_start (*gradient, Gtk::PACK_SHRINK, 2); @@ -298,6 +300,7 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren exposureConn = exposure->signal_toggled().connect (sigc::bind (sigc::mem_fun(*basic, &Gtk::CheckButton::set_inconsistent), true)); shConn = sh->signal_toggled().connect (sigc::bind (sigc::mem_fun(*basic, &Gtk::CheckButton::set_inconsistent), true)); epdConn = epd->signal_toggled().connect (sigc::bind (sigc::mem_fun(*basic, &Gtk::CheckButton::set_inconsistent), true)); + fattalConn = fattal->signal_toggled().connect (sigc::bind (sigc::mem_fun(*basic, &Gtk::CheckButton::set_inconsistent), true)); retinexConn = retinex->signal_toggled().connect (sigc::bind (sigc::mem_fun(*basic, &Gtk::CheckButton::set_inconsistent), true)); pcvignetteConn = pcvignette->signal_toggled().connect (sigc::bind (sigc::mem_fun(*basic, &Gtk::CheckButton::set_inconsistent), true)); gradientConn = gradient->signal_toggled().connect (sigc::bind (sigc::mem_fun(*basic, &Gtk::CheckButton::set_inconsistent), true)); @@ -517,6 +520,7 @@ void PartialPasteDlg::basicToggled () exposure->set_active (basic->get_active ()); sh->set_active (basic->get_active ()); epd->set_active (basic->get_active ()); + fattal->set_active (basic->get_active ()); pcvignette->set_active (basic->get_active ()); gradient->set_active (basic->get_active ()); retinex->set_active (basic->get_active ()); @@ -711,6 +715,10 @@ void PartialPasteDlg::applyPaste (rtengine::procparams::ProcParams* dstPP, Param filterPE.epd = falsePE.epd; } + if (!fattal->get_active ()) { + filterPE.fattal = falsePE.fattal; + } + if (!retinex->get_active ()) { filterPE.retinex = falsePE.retinex; } diff --git a/rtgui/partialpastedlg.h b/rtgui/partialpastedlg.h index 8fa6dbd23..baef6b9aa 100644 --- a/rtgui/partialpastedlg.h +++ b/rtgui/partialpastedlg.h @@ -46,6 +46,7 @@ public: Gtk::CheckButton* exposure; Gtk::CheckButton* sh; Gtk::CheckButton* epd; + Gtk::CheckButton* fattal; Gtk::CheckButton* retinex; Gtk::CheckButton* pcvignette; Gtk::CheckButton* gradient; @@ -124,7 +125,7 @@ public: sigc::connection everythingConn, basicConn, detailConn, colorConn, lensConn, compositionConn, metaConn, rawConn, wavConn; sigc::connection wbConn, exposureConn, shConn, pcvignetteConn, gradientConn, labcurveConn, colorappearanceConn; - sigc::connection sharpenConn, gradsharpenConn, microcontrastConn, impdenConn, dirpyrdenConn, defringeConn, epdConn, dirpyreqConn, waveletConn, retinexConn; + sigc::connection sharpenConn, gradsharpenConn, microcontrastConn, impdenConn, dirpyrdenConn, defringeConn, epdConn, fattalConn, dirpyreqConn, waveletConn, retinexConn; sigc::connection vibranceConn, chmixerConn, hsveqConn, rgbcurvesConn, chmixerbwConn, colortoningConn, filmSimulationConn; sigc::connection distortionConn, cacorrConn, vignettingConn, lcpConn; sigc::connection coarserotConn, finerotConn, cropConn, resizeConn, prsharpeningConn, perspectiveConn, commonTransConn; diff --git a/rtgui/ppversion.h b/rtgui/ppversion.h index 6a695416e..d2e9be090 100644 --- a/rtgui/ppversion.h +++ b/rtgui/ppversion.h @@ -2,11 +2,13 @@ #define _PPVERSION_ // This number has to be incremented whenever the PP3 file format is modified or the behaviour of a tool changes -#define PPVERSION 326 +#define PPVERSION 327 #define PPVERSION_AEXP 301 //value of PPVERSION when auto exposure algorithm was modified /* Log of version changes + 327 2017-09-15 + [Profiles Lens Correction] Added Lensfun 326 2015-07-26 [Exposure] Added 'Perceptual' tone curve mode 325 2015-07-23 diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index f0f35300f..3f414321b 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -187,6 +187,19 @@ Gtk::Widget* Preferences::getBatchProcPanel () appendBehavList (mi, M ("TP_EXPOSURE_CONTRAST"), ADDSET_TC_CONTRAST, false); appendBehavList (mi, M ("TP_EXPOSURE_SATURATION"), ADDSET_TC_SATURATION, false); + mi = behModel->append (); + mi->set_value (behavColumns.label, M ("TP_EPD_LABEL")); + appendBehavList (mi, M ("TP_EPD_STRENGTH"), ADDSET_EPD_STRENGTH, false); + appendBehavList (mi, M ("TP_EPD_GAMMA"), ADDSET_EPD_GAMMA, false); + appendBehavList (mi, M ("TP_EPD_EDGESTOPPING"), ADDSET_EPD_EDGESTOPPING, false); + appendBehavList (mi, M ("TP_EPD_SCALE"), ADDSET_EPD_SCALE, false); + appendBehavList (mi, M ("TP_EPD_REWEIGHTINGITERATES"), ADDSET_EPD_REWEIGHTINGITERATES, false); + + mi = behModel->append (); + mi->set_value (behavColumns.label, M ("TP_TM_FATTAL_LABEL")); + appendBehavList (mi, M ("TP_TM_FATTAL_ALPHA"), ADDSET_FATTAL_ALPHA, false); + appendBehavList (mi, M ("TP_TM_FATTAL_BETA"), ADDSET_FATTAL_BETA, false); + mi = behModel->append (); mi->set_value (behavColumns.label, M ("TP_RETINEX_LABEL")); appendBehavList (mi, M ("TP_RETINEX_STRENGTH"), ADDSET_RETI_STR, false); @@ -210,9 +223,14 @@ Gtk::Widget* Preferences::getBatchProcPanel () appendBehavList (mi, M ("TP_LABCURVE_CONTRAST"), ADDSET_LC_CONTRAST, false); appendBehavList (mi, M ("TP_LABCURVE_CHROMATICITY"), ADDSET_LC_CHROMATICITY, false); - mi = behModel->append (); + mi = behModel->append (); // Used for both Resize and Post-Resize sharpening mi->set_value (behavColumns.label, M ("TP_SHARPENING_LABEL")); + appendBehavList (mi, M ("TP_SHARPENING_RADIUS"), ADDSET_SHARP_RADIUS, false); appendBehavList (mi, M ("TP_SHARPENING_AMOUNT"), ADDSET_SHARP_AMOUNT, false); + appendBehavList (mi, M ("TP_SHARPENING_RLD_DAMPING"), ADDSET_SHARP_DAMPING, false); + appendBehavList (mi, M ("TP_SHARPENING_RLD_ITERATIONS"), ADDSET_SHARP_ITER, false); + appendBehavList (mi, M ("TP_SHARPENING_EDTOLERANCE"), ADDSET_SHARP_EDGETOL, false); + appendBehavList (mi, M ("TP_SHARPENING_HALOCONTROL"), ADDSET_SHARP_HALOCTRL, false); mi = behModel->append (); mi->set_value (behavColumns.label, M ("TP_SHARPENEDGE_LABEL")); @@ -293,6 +311,11 @@ Gtk::Widget* Preferences::getBatchProcPanel () mi->set_value (behavColumns.label, M ("TP_ROTATE_LABEL")); appendBehavList (mi, M ("TP_ROTATE_DEGREE"), ADDSET_ROTATE_DEGREE, false); + mi = behModel->append (); + mi->set_value (behavColumns.label, M ("TP_RESIZE_LABEL")); + appendBehavList (mi, M ("TP_RESIZE_SCALE"), ADDSET_RESIZE_SCALE, true); + + mi = behModel->append (); mi->set_value (behavColumns.label, M ("TP_DISTORTION_LABEL")); appendBehavList (mi, M ("TP_DISTORTION_AMOUNT"), ADDSET_DIST_AMOUNT, false); @@ -334,7 +357,6 @@ Gtk::Widget* Preferences::getBatchProcPanel () mi = behModel->append (); mi->set_value (behavColumns.label, M ("TP_WAVELET_LABEL")); appendBehavList (mi, M ("TP_WAVELET_LEVELS"), ADDSET_WA_THRES, true); - //appendBehavList (mi, M("TP_WAVELET_CONTRAST"), ADDSET_WA, true); appendBehavList (mi, M ("TP_WAVELET_THRESHOLD"), ADDSET_WA_THRESHOLD, true); appendBehavList (mi, M ("TP_WAVELET_THRESHOLD2"), ADDSET_WA_THRESHOLD2, true); appendBehavList (mi, M ("TP_WAVELET_CHRO"), ADDSET_WA_CHRO, true); @@ -411,22 +433,21 @@ void Preferences::appendBehavList (Gtk::TreeModel::iterator& parent, Glib::ustri ci->set_value (behavColumns.addsetid, id); } +void Preferences::behAddSetRadioToggled (const Glib::ustring& path, bool add) +{ + Gtk::TreeModel::iterator iter = behModel->get_iter (path); + iter->set_value(behavColumns.badd, add); + iter->set_value(behavColumns.bset, !add); +} + void Preferences::behAddRadioToggled (const Glib::ustring& path) { - - Gtk::TreeModel::iterator iter = behModel->get_iter (path); - //bool set = iter->get_value (behavColumns.bset); - iter->set_value (behavColumns.bset, false); - iter->set_value (behavColumns.badd, true); + behAddSetRadioToggled(path, true); } void Preferences::behSetRadioToggled (const Glib::ustring& path) { - - Gtk::TreeModel::iterator iter = behModel->get_iter (path); - //bool add = iter->get_value (behavColumns.badd); - iter->set_value (behavColumns.bset, true); - iter->set_value (behavColumns.badd, false); + behAddSetRadioToggled(path, false); } @@ -505,51 +526,56 @@ Gtk::Widget* Preferences::getProcParamsPanel () fdp->add (*vbdp); mvbpp->pack_start (*fdp, Gtk::PACK_SHRINK, 4); - Gtk::Frame* fdf = Gtk::manage (new Gtk::Frame (M ("PREFERENCES_DARKFRAME")) ); - Gtk::HBox* hb42 = Gtk::manage (new Gtk::HBox ()); - darkFrameDir = Gtk::manage (new Gtk::FileChooserButton (M ("PREFERENCES_DIRDARKFRAMES"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); + // Directories + Gtk::Frame* cdf = Gtk::manage (new Gtk::Frame (M ("PREFERENCES_DIRECTORIES")) ); + Gtk::Grid* dirgrid = Gtk::manage (new Gtk::Grid ()); + setExpandAlignProperties(dirgrid, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + Gtk::Label *dfLab = Gtk::manage (new Gtk::Label (M ("PREFERENCES_DIRDARKFRAMES") + ":")); - hb42->pack_start (*dfLab, Gtk::PACK_SHRINK, 4 ); - hb42->pack_start (*darkFrameDir, Gtk::PACK_EXPAND_WIDGET, 4); + setExpandAlignProperties(dfLab, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + darkFrameDir = Gtk::manage (new MyFileChooserButton (M ("PREFERENCES_DIRDARKFRAMES"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); + setExpandAlignProperties(darkFrameDir, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); dfLabel = Gtk::manage (new Gtk::Label ("Found:")); - Gtk::VBox* vbdf = Gtk::manage (new Gtk::VBox ()); - vbdf->pack_start (*hb42, Gtk::PACK_SHRINK, 4); - vbdf->pack_start (*dfLabel, Gtk::PACK_SHRINK, 4 ); - fdf->add (*vbdf ); - mvbpp->pack_start (*fdf, Gtk::PACK_SHRINK, 4); + setExpandAlignProperties(dfLabel, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + + dirgrid->attach_next_to(*dfLab, Gtk::POS_TOP, 1, 1); + dirgrid->attach_next_to(*darkFrameDir, *dfLab, Gtk::POS_RIGHT, 1, 1); + dirgrid->attach_next_to(*dfLabel, *darkFrameDir, Gtk::POS_RIGHT, 1, 1); //dfconn = darkFrameDir->signal_file_set().connect ( sigc::mem_fun(*this, &Preferences::darkFrameChanged), true); - dfconn = darkFrameDir->signal_selection_changed().connect ( sigc::mem_fun (*this, &Preferences::darkFrameChanged), true); + dfconn = darkFrameDir->signal_selection_changed().connect ( sigc::mem_fun (*this, &Preferences::darkFrameChanged)); //, true); // FLATFIELD - Gtk::Frame* fff = Gtk::manage (new Gtk::Frame (M ("PREFERENCES_FLATFIELD")) ); - Gtk::HBox* hb43 = Gtk::manage (new Gtk::HBox ()); - flatFieldDir = Gtk::manage (new Gtk::FileChooserButton (M ("PREFERENCES_FLATFIELDSDIR"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); Gtk::Label *ffLab = Gtk::manage (new Gtk::Label (M ("PREFERENCES_FLATFIELDSDIR") + ":")); - hb43->pack_start (*ffLab, Gtk::PACK_SHRINK, 4 ); - hb43->pack_start (*flatFieldDir); + setExpandAlignProperties(ffLab, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + flatFieldDir = Gtk::manage (new MyFileChooserButton (M ("PREFERENCES_FLATFIELDSDIR"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); + setExpandAlignProperties(flatFieldDir, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); ffLabel = Gtk::manage (new Gtk::Label ("Found:")); - Gtk::VBox* vbff = Gtk::manage (new Gtk::VBox ()); - vbff->pack_start (*hb43, Gtk::PACK_SHRINK, 4); - vbff->pack_start (*ffLabel, Gtk::PACK_SHRINK, 4 ); - fff->add (*vbff ); - mvbpp->pack_start (*fff, Gtk::PACK_SHRINK, 4); + setExpandAlignProperties(ffLabel, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + + dirgrid->attach_next_to(*ffLab, *dfLab, Gtk::POS_BOTTOM, 1, 1); + dirgrid->attach_next_to(*flatFieldDir, *ffLab, Gtk::POS_RIGHT, 1, 1); + dirgrid->attach_next_to(*ffLabel, *flatFieldDir, Gtk::POS_RIGHT, 1, 1); //ffconn = flatFieldDir->signal_file_set().connect ( sigc::mem_fun(*this, &Preferences::flatFieldChanged), true); - ffconn = flatFieldDir->signal_selection_changed().connect ( sigc::mem_fun (*this, &Preferences::flatFieldChanged), true); + ffconn = flatFieldDir->signal_selection_changed().connect ( sigc::mem_fun (*this, &Preferences::flatFieldChanged)); //, true); //Cluts Dir - Gtk::Frame* clutsDirFrame = Gtk::manage (new Gtk::Frame (M ("PREFERENCES_FILMSIMULATION")) ); - Gtk::HBox* clutsDirBox = Gtk::manage (new Gtk::HBox ()); - clutsDir = Gtk::manage (new Gtk::FileChooserButton (M ("PREFERENCES_CLUTSDIR"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); Gtk::Label *clutsDirLabel = Gtk::manage (new Gtk::Label (M ("PREFERENCES_CLUTSDIR") + ":")); + setExpandAlignProperties(clutsDirLabel, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + clutsDir = Gtk::manage (new MyFileChooserButton (M ("PREFERENCES_CLUTSDIR"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); + setExpandAlignProperties(clutsDir, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); Gtk::Label* clutsRestartNeeded = Gtk::manage ( new Gtk::Label (Glib::ustring (" (") + M ("PREFERENCES_APPLNEXTSTARTUP") + ")") ); - clutsDirBox->pack_start (*clutsDirLabel, Gtk::PACK_SHRINK, 4 ); - clutsDirBox->pack_start (*clutsDir ); - clutsDirBox->pack_start (*clutsRestartNeeded, Gtk::PACK_SHRINK, 4 ); - clutsDirFrame->add (*clutsDirBox ); - mvbpp->pack_start (*clutsDirFrame, Gtk::PACK_SHRINK, 4 ); + setExpandAlignProperties(clutsRestartNeeded, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + dirgrid->attach_next_to(*clutsDirLabel, *ffLab, Gtk::POS_BOTTOM, 1, 1); + dirgrid->attach_next_to(*clutsDir, *clutsDirLabel, Gtk::POS_RIGHT, 1, 1); + dirgrid->attach_next_to(*clutsRestartNeeded, *clutsDir, Gtk::POS_RIGHT, 1, 1); + + cdf->add(*dirgrid); + mvbpp->pack_start (*cdf, Gtk::PACK_SHRINK, 4 ); + + // Metadata Gtk::Frame* fmd = Gtk::manage (new Gtk::Frame (M ("PREFERENCES_METADATA"))); Gtk::VBox* vbmd = Gtk::manage (new Gtk::VBox ()); ckbTunnelMetaData = Gtk::manage (new Gtk::CheckButton (M ("PREFERENCES_TUNNELMETADATA"))); @@ -707,7 +733,7 @@ Gtk::Widget* Preferences::getColorManagementPanel () Gtk::VBox* mvbcm = Gtk::manage (new Gtk::VBox ()); mvbcm->set_spacing (4); - iccDir = Gtk::manage (new Gtk::FileChooserButton (M ("PREFERENCES_ICCDIR"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); + iccDir = Gtk::manage (new MyFileChooserButton (M ("PREFERENCES_ICCDIR"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); setExpandAlignProperties (iccDir, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); Gtk::Label* pdlabel = Gtk::manage (new Gtk::Label (M ("PREFERENCES_ICCDIR") + ":", Gtk::ALIGN_START)); setExpandAlignProperties (pdlabel, false, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); @@ -878,14 +904,14 @@ Gtk::Widget* Preferences::getColorManagementPanel () grey->append (M("PREFERENCES_GREY30")); grey->append (M("PREFERENCES_GREY40")); */ -/* - Gtk::Label* greySclab = Gtk::manage (new Gtk::Label (M ("PREFERENCES_GREYSC") + ":", Gtk::ALIGN_START)); - setExpandAlignProperties (greySclab, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - greySc = Gtk::manage (new Gtk::ComboBoxText ()); - setExpandAlignProperties (greySc, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - greySc->append (M ("PREFERENCES_GREYSCA")); - greySc->append (M ("PREFERENCES_GREYSC18")); -*/ + /* + Gtk::Label* greySclab = Gtk::manage (new Gtk::Label (M ("PREFERENCES_GREYSC") + ":", Gtk::ALIGN_START)); + setExpandAlignProperties (greySclab, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + greySc = Gtk::manage (new Gtk::ComboBoxText ()); + setExpandAlignProperties (greySc, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + greySc->append (M ("PREFERENCES_GREYSCA")); + greySc->append (M ("PREFERENCES_GREYSC18")); + */ Gtk::Frame* fcielab = Gtk::manage ( new Gtk::Frame (M ("PREFERENCES_CIEART_FRAME")) ); setExpandAlignProperties (fcielab, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); @@ -986,8 +1012,20 @@ Gtk::Widget* Preferences::getGeneralPanel () workflowGrid->attach_next_to (*hb4label, *ckbFileBrowserToolbarSingleRow, Gtk::POS_BOTTOM, 1, 1); workflowGrid->attach_next_to (*ckbHideTPVScrollbar, *hb4label, Gtk::POS_RIGHT, 1, 1); workflowGrid->attach_next_to (*ckbUseIconNoText, *ckbHideTPVScrollbar, Gtk::POS_RIGHT, 1, 1); + ckbAutoSaveTpOpen = Gtk::manage (new Gtk::CheckButton (M ("PREFERENCES_AUTOSAVE_TP_OPEN"))); + workflowGrid->attach_next_to (*ckbAutoSaveTpOpen, *hb4label, Gtk::POS_BOTTOM, 1, 1); + btnSaveTpOpenNow = Gtk::manage (new Gtk::Button (M ("PREFERENCES_SAVE_TP_OPEN_NOW"))); + setExpandAlignProperties (btnSaveTpOpenNow, false, false, Gtk::ALIGN_START, Gtk::ALIGN_BASELINE); + workflowGrid->attach_next_to (*btnSaveTpOpenNow, *ckbAutoSaveTpOpen, Gtk::POS_RIGHT, 1, 1); + + auto save_tp_open_now = + [&]() -> void { + parent->writeToolExpandedStatus (moptions.tpOpen); + }; + btnSaveTpOpenNow->signal_clicked().connect (save_tp_open_now); fworklflow->add (*workflowGrid); + mvbsd->attach_next_to (*fworklflow, Gtk::POS_TOP, 2, 1); // --------------------------------------------- @@ -1182,7 +1220,7 @@ Gtk::Widget* Preferences::getGeneralPanel () edPS = Gtk::manage ( new Gtk::RadioButton (M ("PREFERENCES_PSPATH") + ":")); setExpandAlignProperties (edPS, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - psDir = Gtk::manage ( new Gtk::FileChooserButton (M ("PREFERENCES_PSPATH"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER) ); + psDir = Gtk::manage ( new MyFileChooserButton (M ("PREFERENCES_PSPATH"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER) ); setExpandAlignProperties (psDir, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); externaleditorGrid->attach_next_to (*edPS, *edGimp, Gtk::POS_BOTTOM, 1, 1); externaleditorGrid->attach_next_to (*psDir, *edPS, Gtk::POS_RIGHT, 1, 1); @@ -1193,7 +1231,7 @@ Gtk::Widget* Preferences::getGeneralPanel () #elif defined WIN32 edGimp = Gtk::manage ( new Gtk::RadioButton (M ("PREFERENCES_GIMPPATH") + ":") ); setExpandAlignProperties (edGimp, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - gimpDir = Gtk::manage ( new Gtk::FileChooserButton (M ("PREFERENCES_GIMPPATH"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER) ); + gimpDir = Gtk::manage ( new MyFileChooserButton (M ("PREFERENCES_GIMPPATH"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER) ); setExpandAlignProperties (gimpDir, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); externaleditorGrid->attach_next_to (*edGimp, Gtk::POS_TOP, 1, 1); externaleditorGrid->attach_next_to (*gimpDir, *edGimp, Gtk::POS_RIGHT, 1, 1); @@ -1201,7 +1239,7 @@ Gtk::Widget* Preferences::getGeneralPanel () edPS = Gtk::manage ( new Gtk::RadioButton (M ("PREFERENCES_PSPATH") + ":") ); setExpandAlignProperties (edPS, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - psDir = Gtk::manage ( new Gtk::FileChooserButton (M ("PREFERENCES_PSPATH"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER) ); + psDir = Gtk::manage ( new MyFileChooserButton (M ("PREFERENCES_PSPATH"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER) ); setExpandAlignProperties (psDir, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); externaleditorGrid->attach_next_to (*edPS, *edGimp, Gtk::POS_BOTTOM, 1, 1); externaleditorGrid->attach_next_to (*psDir, *edPS, Gtk::POS_RIGHT, 1, 1); @@ -1792,6 +1830,8 @@ void Preferences::storePreferences () moptions.overwriteOutputFile = chOverwriteOutputFile->get_active (); moptions.UseIconNoText = ckbUseIconNoText->get_active(); + moptions.autoSaveTpOpen = ckbAutoSaveTpOpen->get_active(); + moptions.rgbDenoiseThreadLimit = rgbDenoiseTreadLimitSB->get_value_as_int(); moptions.clutCacheSize = clutCacheSizeSB->get_value_as_int(); moptions.maxInspectorBuffers = maxInspectorBuffersSB->get_value_as_int(); @@ -2009,6 +2049,8 @@ void Preferences::fillPreferences () ckbHideTPVScrollbar->set_active (moptions.hideTPVScrollbar); ckbUseIconNoText->set_active (moptions.UseIconNoText); + ckbAutoSaveTpOpen->set_active (moptions.autoSaveTpOpen); + rgbDenoiseTreadLimitSB->set_value (moptions.rgbDenoiseThreadLimit); clutCacheSizeSB->set_value (moptions.clutCacheSize); maxInspectorBuffersSB->set_value (moptions.maxInspectorBuffers); @@ -2026,14 +2068,13 @@ void Preferences::fillPreferences () moptions.baBehav.resize (ADDSET_PARAM_NUM); - for (size_t i = 0; i < moptions.baBehav.size(); i++) - for (Gtk::TreeIter sections = behModel->children().begin(); sections != behModel->children().end(); sections++) - for (Gtk::TreeIter adjs = sections->children().begin(); adjs != sections->children().end(); adjs++) - if (adjs->get_value (behavColumns.addsetid) == (int)i) { - adjs->set_value (behavColumns.badd, moptions.baBehav[i] == 1); - adjs->set_value (behavColumns.bset, moptions.baBehav[i] != 1); - break; - } + for (Gtk::TreeIter sections = behModel->children().begin(); sections != behModel->children().end(); ++sections) { + for (Gtk::TreeIter adjs = sections->children().begin(); adjs != sections->children().end(); ++adjs) { + const bool add = moptions.baBehav[adjs->get_value(behavColumns.addsetid)]; + adjs->set_value (behavColumns.badd, add); + adjs->set_value (behavColumns.bset, !add); + } + } addc.block (false); setc.block (false); @@ -2103,7 +2144,14 @@ void Preferences::okPressed () workflowUpdate(); options.copyFrom (&moptions); options.filterOutParsedExtensions(); - Options::save (); + + try { + Options::save (); + } catch (Options::Error &e) { + Gtk::MessageDialog msgd (getToplevelWindow (this), e.get_msg(), true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_CLOSE, true); + msgd.run(); + } + dynProfilePanel->save(); hide (); } @@ -2112,7 +2160,7 @@ void Preferences::cancelPressed () { // set the initial theme back if (themeFNames.at (theme->get_active_row_number ()).longFName != options.theme) { - rtengine::setPaths (options); + rtengine::setPaths(); RTImage::updateImages(); switchThemeTo (options.theme); } @@ -2170,7 +2218,7 @@ void Preferences::themeChanged () { moptions.theme = themeFNames.at (theme->get_active_row_number ()).longFName; - rtengine::setPaths (moptions); + rtengine::setPaths(); RTImage::updateImages(); switchThemeTo (moptions.theme); } @@ -2531,32 +2579,23 @@ bool Preferences::splashClosed (GdkEventAny* event) return true; } +void Preferences::behAddSetAllPressed (bool add) +{ + moptions.baBehav.assign(ADDSET_PARAM_NUM, add); + for (Gtk::TreeIter sections = behModel->children().begin(); sections != behModel->children().end(); ++sections) { + for (Gtk::TreeIter adjs = sections->children().begin(); adjs != sections->children().end(); ++adjs) { + adjs->set_value(behavColumns.badd, add); + adjs->set_value(behavColumns.bset, !add); + } + } +} + void Preferences::behAddAllPressed () { - - if (moptions.baBehav.size() == ADDSET_PARAM_NUM) { - for (size_t i = 0; i < moptions.baBehav.size(); i++) - for (Gtk::TreeIter sections = behModel->children().begin(); sections != behModel->children().end(); sections++) - for (Gtk::TreeIter adjs = sections->children().begin(); adjs != sections->children().end(); adjs++) - if (adjs->get_value (behavColumns.addsetid) == (int)i) { - adjs->set_value (behavColumns.badd, true); - adjs->set_value (behavColumns.bset, false); - break; - } - } + behAddSetAllPressed(true); } void Preferences::behSetAllPressed () { - - if (moptions.baBehav.size() == ADDSET_PARAM_NUM) { - for (size_t i = 0; i < moptions.baBehav.size(); i++) - for (Gtk::TreeIter sections = behModel->children().begin(); sections != behModel->children().end(); sections++) - for (Gtk::TreeIter adjs = sections->children().begin(); adjs != sections->children().end(); adjs++) - if (adjs->get_value (behavColumns.addsetid) == (int)i) { - adjs->set_value (behavColumns.badd, false); - adjs->set_value (behavColumns.bset, true); - break; - } - } + behAddSetAllPressed(false); } diff --git a/rtgui/preferences.h b/rtgui/preferences.h index 1a86c64a9..b3efd8b6a 100644 --- a/rtgui/preferences.h +++ b/rtgui/preferences.h @@ -36,8 +36,8 @@ class Preferences : public Gtk::Dialog, public ProfileStoreListener Gtk::TreeModelColumn ext; ExtensionColumns() { - add(enabled); - add(ext); + add (enabled); + add (ext); } }; ExtensionColumns extensionColumns; @@ -54,11 +54,11 @@ class Preferences : public Gtk::Dialog, public ProfileStoreListener Gtk::TreeModelColumn addsetid; BehavColumns() { - add(label); - add(badd); - add(bset); - add(visible); - add(addsetid); + add (label); + add (badd); + add (bset); + add (visible); + add (addsetid); } }; @@ -68,7 +68,7 @@ class Preferences : public Gtk::Dialog, public ProfileStoreListener Glib::ustring shortFName; Glib::ustring longFName; - ThemeFilename (Glib::ustring sfname, Glib::ustring lfname) : shortFName(sfname), longFName(lfname) {} + ThemeFilename (Glib::ustring sfname, Glib::ustring lfname) : shortFName (sfname), longFName (lfname) {} }; Glib::RefPtr behModel; @@ -89,15 +89,15 @@ class Preferences : public Gtk::Dialog, public ProfileStoreListener Gtk::RadioButton* sdlast; Gtk::RadioButton* sdhome; Gtk::RadioButton* sdother; - Gtk::FileChooserButton* gimpDir; - Gtk::FileChooserButton* psDir; + MyFileChooserButton* gimpDir; + MyFileChooserButton* psDir; Gtk::Entry* editorToSendTo; Gtk::RadioButton* edGimp; Gtk::RadioButton* edPS; Gtk::RadioButton* edOther; - Gtk::FileChooserButton* darkFrameDir; - Gtk::FileChooserButton* flatFieldDir; - Gtk::FileChooserButton* clutsDir; + MyFileChooserButton* darkFrameDir; + MyFileChooserButton* flatFieldDir; + MyFileChooserButton* clutsDir; Gtk::Label *dfLabel; Gtk::Label *ffLabel; @@ -105,7 +105,7 @@ class Preferences : public Gtk::Dialog, public ProfileStoreListener Gtk::CheckButton* showBasicExif; Gtk::CheckButton* showExpComp; - Gtk::FileChooserButton* iccDir; + MyFileChooserButton* iccDir; Gtk::ComboBoxText* prtProfile; Gtk::ComboBoxText* prtIntent; Gtk::CheckButton* prtBPC; @@ -122,7 +122,7 @@ class Preferences : public Gtk::Dialog, public ProfileStoreListener Gtk::SpinButton* panFactor; Gtk::CheckButton* rememberZoomPanCheckbutton; - // Gtk::ComboBoxText* view; +// Gtk::ComboBoxText* view; // Gtk::ComboBoxText* grey; // Gtk::ComboBoxText* greySc; Gtk::ComboBoxText* dnv; @@ -201,6 +201,9 @@ class Preferences : public Gtk::Dialog, public ProfileStoreListener Gtk::CheckButton* ckbHideTPVScrollbar; Gtk::CheckButton* ckbUseIconNoText; + Gtk::CheckButton* ckbAutoSaveTpOpen; + Gtk::Button* btnSaveTpOpenNow; + DynamicProfilePanel *dynProfilePanel; Glib::ustring storedValueRaw; @@ -232,9 +235,9 @@ class Preferences : public Gtk::Dialog, public ProfileStoreListener void iccDirChanged (); void switchThemeTo (Glib::ustring newTheme); void switchFontTo (const Glib::ustring &newFontFamily, const int newFontSize); - bool splashClosed(GdkEventAny* event); + bool splashClosed (GdkEventAny* event); - int getThemeRowNumber(Glib::ustring& longThemeFName); + int getThemeRowNumber (Glib::ustring& longThemeFName); void appendBehavList (Gtk::TreeModel::iterator& parent, Glib::ustring label, int id, bool set); @@ -272,8 +275,10 @@ public: void clearThumbImagesPressed (); void clearAllPressed (); + void behAddSetRadioToggled (const Glib::ustring& path, bool add); void behAddRadioToggled (const Glib::ustring& path); void behSetRadioToggled (const Glib::ustring& path); + void behAddSetAllPressed (bool add); void behAddAllPressed (); void behSetAllPressed (); diff --git a/rtgui/previewmodepanel.cc b/rtgui/previewmodepanel.cc index 50beb8b66..60b450e4a 100644 --- a/rtgui/previewmodepanel.cc +++ b/rtgui/previewmodepanel.cc @@ -28,19 +28,19 @@ PreviewModePanel::PreviewModePanel (ImageArea* ia) : imageArea(ia) iG = new RTImage ("previewmodeG-on.png"); iB = new RTImage ("previewmodeB-on.png"); iL = new RTImage ("previewmodeL-on.png"); - iF = new RTImage ("previewmodeF-on.png"); iBC0 = new RTImage ("previewmodeBC0-on.png"); iBC1 = new RTImage ("previewmodeBC1-on.png"); iBC2 = new RTImage ("previewmodeBC2-on.png"); + iBC3 = new RTImage ("previewmodeBC3-on.png"); igR = new RTImage ("previewmodeR-off.png"); igG = new RTImage ("previewmodeG-off.png"); igB = new RTImage ("previewmodeB-off.png"); igL = new RTImage ("previewmodeL-off.png"); - igF = new RTImage ("previewmodeF-off.png"); igBC0 = new RTImage ("previewmodeBC0-off.png"); igBC1 = new RTImage ("previewmodeBC1-off.png"); igBC2 = new RTImage ("previewmodeBC2-off.png"); + igBC3 = new RTImage ("previewmodeBC3-off.png"); backColor0 = Gtk::manage (new Gtk::ToggleButton ()); backColor0->set_relief(Gtk::RELIEF_NONE); @@ -52,6 +52,11 @@ PreviewModePanel::PreviewModePanel (ImageArea* ia) : imageArea(ia) backColor1->set_tooltip_markup (M("MAIN_TOOLTIP_BACKCOLOR1")); backColor1->set_image(options.bgcolor == 1 ? *iBC1 : *igBC1); + backColor3 = Gtk::manage (new Gtk::ToggleButton ()); + backColor3->set_relief(Gtk::RELIEF_NONE); + backColor3->set_tooltip_markup (M("MAIN_TOOLTIP_BACKCOLOR3")); + backColor3->set_image(options.bgcolor == 3 ? *iBC3 : *igBC3); + backColor2 = Gtk::manage (new Gtk::ToggleButton ()); backColor2->set_relief(Gtk::RELIEF_NONE); backColor2->set_tooltip_markup (M("MAIN_TOOLTIP_BACKCOLOR2")); @@ -77,42 +82,37 @@ PreviewModePanel::PreviewModePanel (ImageArea* ia) : imageArea(ia) previewL->set_tooltip_markup (M("MAIN_TOOLTIP_PREVIEWL")); previewL->set_image(*igL); - previewFocusMask = Gtk::manage (new Gtk::ToggleButton ()); - previewFocusMask->set_relief(Gtk::RELIEF_NONE); - previewFocusMask->set_tooltip_markup (M("MAIN_TOOLTIP_PREVIEWFOCUSMASK")); - previewFocusMask->set_image(*igF); - previewR->set_active (false); previewG->set_active (false); previewB->set_active (false); previewL->set_active (false); - previewFocusMask->set_active (false); backColor0->set_active (options.bgcolor == 0); backColor1->set_active (options.bgcolor == 1); backColor2->set_active (options.bgcolor == 2); + backColor3->set_active (options.bgcolor == 3); - vbbackColor = Gtk::manage (new Gtk::VBox ()); - vbbackColor->pack_start (*backColor0, Gtk::PACK_SHRINK, 0); - vbbackColor->pack_start (*backColor1, Gtk::PACK_SHRINK, 0); - vbbackColor->pack_start (*backColor2, Gtk::PACK_SHRINK, 0); - pack_start (*vbbackColor, Gtk::PACK_SHRINK, 0); + pack_start (*backColor0, Gtk::PACK_SHRINK, 0); + pack_start (*backColor1, Gtk::PACK_SHRINK, 0); + pack_start (*backColor3, Gtk::PACK_SHRINK, 0); + pack_start (*backColor2, Gtk::PACK_SHRINK, 0); + + pack_start (*Gtk::manage (new Gtk::VSeparator ()), Gtk::PACK_SHRINK, 2); pack_start (*previewR, Gtk::PACK_SHRINK, 0); pack_start (*previewG, Gtk::PACK_SHRINK, 0); pack_start (*previewB, Gtk::PACK_SHRINK, 0); pack_start (*previewL, Gtk::PACK_SHRINK, 0); - pack_start (*previewFocusMask, Gtk::PACK_SHRINK, 0); connR = previewR->signal_toggled().connect( sigc::bind(sigc::mem_fun(*this, &PreviewModePanel::buttonToggled), previewR) ); connG = previewG->signal_toggled().connect( sigc::bind(sigc::mem_fun(*this, &PreviewModePanel::buttonToggled), previewG) ); connB = previewB->signal_toggled().connect( sigc::bind(sigc::mem_fun(*this, &PreviewModePanel::buttonToggled), previewB) ); connL = previewL->signal_toggled().connect( sigc::bind(sigc::mem_fun(*this, &PreviewModePanel::buttonToggled), previewL) ); - connFocusMask = previewFocusMask->signal_toggled().connect( sigc::bind(sigc::mem_fun(*this, &PreviewModePanel::buttonToggled), previewFocusMask) ); connbackColor0 = backColor0->signal_toggled().connect( sigc::bind(sigc::mem_fun(*this, &PreviewModePanel::buttonToggled_backColor), backColor0) ); connbackColor1 = backColor1->signal_toggled().connect( sigc::bind(sigc::mem_fun(*this, &PreviewModePanel::buttonToggled_backColor), backColor1) ); connbackColor2 = backColor2->signal_toggled().connect( sigc::bind(sigc::mem_fun(*this, &PreviewModePanel::buttonToggled_backColor), backColor2) ); + connbackColor3 = backColor3->signal_toggled().connect( sigc::bind(sigc::mem_fun(*this, &PreviewModePanel::buttonToggled_backColor), backColor3) ); //show_all (); } @@ -123,18 +123,18 @@ PreviewModePanel::~PreviewModePanel () delete iG; delete iB; delete iL; - delete iF; delete iBC0; delete iBC1; delete iBC2; + delete iBC3; delete igR; delete igG; delete igB; delete igL; - delete igF; delete igBC0; delete igBC1; delete igBC2; + delete igBC3; } //toggle Functions below are for shortcuts void PreviewModePanel::toggleR () @@ -153,10 +153,6 @@ void PreviewModePanel::toggleL () { previewL->set_active(!previewL->get_active()); } -void PreviewModePanel::toggleFocusMask () -{ - previewFocusMask->set_active(!previewFocusMask->get_active()); -} void PreviewModePanel::togglebackColor0 () { @@ -170,6 +166,10 @@ void PreviewModePanel::togglebackColor2 () { backColor2->set_active(!backColor2->get_active()); } +void PreviewModePanel::togglebackColor3 () +{ + backColor3->set_active(!backColor3->get_active()); +} void PreviewModePanel::buttonToggled (Gtk::ToggleButton* tbpreview) { @@ -178,7 +178,6 @@ void PreviewModePanel::buttonToggled (Gtk::ToggleButton* tbpreview) connG.block(true); connB.block(true); connL.block(true); - connFocusMask.block(true); // control state of the buttons // only 0 or 1 button at a time can remain pressed @@ -198,22 +197,16 @@ void PreviewModePanel::buttonToggled (Gtk::ToggleButton* tbpreview) previewL->set_active(false); } - if (tbpreview != previewFocusMask) { - previewFocusMask->set_active(false); - } - // set image based on button's state previewR->set_image(previewR->get_active() ? *iR : *igR); previewG->set_image(previewG->get_active() ? *iG : *igG); previewB->set_image(previewB->get_active() ? *iB : *igB); previewL->set_image(previewL->get_active() ? *iL : *igL); - previewFocusMask->set_image(previewFocusMask->get_active() ? *iF : *igF); connR.block(false); connG.block(false); connB.block(false); connL.block(false); - connFocusMask.block(false); imageArea->queue_draw (); @@ -240,6 +233,10 @@ int PreviewModePanel::GetbackColor() backColor = 2; } + if (backColor3->get_active ()) { + backColor = 3; + } + return backColor; } @@ -250,6 +247,8 @@ void PreviewModePanel::togglebackColor() if(backColor == 0) { togglebackColor1(); } else if(backColor == 1) { + togglebackColor3(); + } else if(backColor == 3) { togglebackColor2(); } else { togglebackColor0(); @@ -262,6 +261,7 @@ void PreviewModePanel::buttonToggled_backColor (Gtk::ToggleButton* tbbackColor) connbackColor0.block(true); connbackColor1.block(true); connbackColor2.block(true); + connbackColor3.block(true); // control the state of the buttons // Exactly 1 button at a time must remain pressed @@ -277,6 +277,10 @@ void PreviewModePanel::buttonToggled_backColor (Gtk::ToggleButton* tbbackColor) backColor2->set_active(true); } + if (tbbackColor == backColor3 && !backColor3->get_active()) { + backColor3->set_active(true); + } + if (tbbackColor != backColor0) { backColor0->set_active(false); } @@ -289,14 +293,20 @@ void PreviewModePanel::buttonToggled_backColor (Gtk::ToggleButton* tbbackColor) backColor2->set_active(false); } + if (tbbackColor != backColor3) { + backColor3->set_active(false); + } + // set image based on button's state backColor0->set_image(backColor0->get_active() ? *iBC0 : *igBC0); backColor1->set_image(backColor1->get_active() ? *iBC1 : *igBC1); backColor2->set_image(backColor2->get_active() ? *iBC2 : *igBC2); + backColor3->set_image(backColor3->get_active() ? *iBC3 : *igBC3); connbackColor0.block(false); connbackColor1.block(false); connbackColor2.block(false); + connbackColor3.block(false); //TODO not sure if queue_draw is necessary, but will need to reach to backColor of the Before view imageArea->queue_draw (); diff --git a/rtgui/previewmodepanel.h b/rtgui/previewmodepanel.h index d3bf3c8e4..1d7b99625 100644 --- a/rtgui/previewmodepanel.h +++ b/rtgui/previewmodepanel.h @@ -30,21 +30,20 @@ protected: Gtk::ToggleButton* previewG; Gtk::ToggleButton* previewB; Gtk::ToggleButton* previewL; - Gtk::ToggleButton* previewFocusMask; Gtk::ToggleButton* backColor0; Gtk::ToggleButton* backColor1; Gtk::ToggleButton* backColor2; - Gtk::VBox* vbbackColor; + Gtk::ToggleButton* backColor3; ImageArea* imageArea; Gtk::Image* iR, *igR; Gtk::Image* iG, *igG; Gtk::Image* iB, *igB; Gtk::Image* iL, *igL; - Gtk::Image* iF, *igF; Gtk::Image* iBC0, *igBC0; Gtk::Image* iBC1, *igBC1; Gtk::Image* iBC2, *igBC2; + Gtk::Image* iBC3, *igBC3; public: explicit PreviewModePanel (ImageArea* ia); @@ -54,13 +53,13 @@ public: void toggleG (); void toggleB (); void toggleL (); - void toggleFocusMask (); void togglebackColor0(); void togglebackColor1(); void togglebackColor2(); + void togglebackColor3(); void togglebackColor(); - sigc::connection connR, connB, connG, connL, connFocusMask, connbackColor0, connbackColor1, connbackColor2; + sigc::connection connR, connB, connG, connL, connbackColor0, connbackColor1, connbackColor2, connbackColor3; void buttonToggled(Gtk::ToggleButton* tbpreview); void buttonToggled_backColor(Gtk::ToggleButton* tbbackColor); @@ -81,10 +80,6 @@ public: { return previewL->get_active (); } - bool showFocusMask () - { - return previewFocusMask->get_active (); - } int GetbackColor(); }; diff --git a/rtgui/profilepanel.cc b/rtgui/profilepanel.cc index 6d317f5a4..57204f8b1 100644 --- a/rtgui/profilepanel.cc +++ b/rtgui/profilepanel.cc @@ -26,12 +26,12 @@ using namespace rtengine; using namespace rtengine::procparams; -PartialPasteDlg* ProfilePanel::partialProfileDlg; +PartialPasteDlg* ProfilePanel::partialProfileDlg = nullptr; +Gtk::Window* ProfilePanel::parent; - -void ProfilePanel::init (Gtk::Window* parent) +void ProfilePanel::init (Gtk::Window* parentWindow) { - partialProfileDlg = new PartialPasteDlg (Glib::ustring (), parent); + parent = parentWindow; } void ProfilePanel::cleanup () @@ -336,6 +336,9 @@ void ProfilePanel::save_clicked (GdkEventButton* event) if (toSave) { if (event->state & Gdk::CONTROL_MASK) { // opening the partial paste dialog window + if(!partialProfileDlg) { + partialProfileDlg = new PartialPasteDlg (Glib::ustring (), parent); + } partialProfileDlg->set_title(M("PROFILEPANEL_SAVEPPASTE")); int i = partialProfileDlg->run(); partialProfileDlg->hide(); @@ -407,6 +410,9 @@ void ProfilePanel::copy_clicked (GdkEventButton* event) if (toSave) { if (event->state & Gdk::CONTROL_MASK) { // opening the partial paste dialog window + if(!partialProfileDlg) { + partialProfileDlg = new PartialPasteDlg (Glib::ustring (), parent); + } partialProfileDlg->set_title(M("PROFILEPANEL_COPYPPASTE")); int i = partialProfileDlg->run(); partialProfileDlg->hide(); @@ -475,6 +481,9 @@ void ProfilePanel::load_clicked (GdkEventButton* event) if (event->state & Gdk::CONTROL_MASK) { // opening the partial paste dialog window + if(!partialProfileDlg) { + partialProfileDlg = new PartialPasteDlg (Glib::ustring (), parent); + } partialProfileDlg->set_title(M("PROFILEPANEL_LOADPPASTE")); int i = partialProfileDlg->run(); partialProfileDlg->hide(); @@ -514,6 +523,9 @@ void ProfilePanel::load_clicked (GdkEventButton* event) if (event->state & Gdk::CONTROL_MASK) // custom.pparams = loadedFile.pparams filtered by ( loadedFile.pedited & partialPaste.pedited ) { + if(!partialProfileDlg) { + partialProfileDlg = new PartialPasteDlg (Glib::ustring (), parent); + } partialProfileDlg->applyPaste (custom->pparams, !fillMode->get_active() ? custom->pedited : nullptr, &pp, &pe); } else { // custom.pparams = loadedFile.pparams filtered by ( loadedFile.pedited ) @@ -551,6 +563,9 @@ void ProfilePanel::paste_clicked (GdkEventButton* event) } if (event->state & Gdk::CONTROL_MASK) { + if(!partialProfileDlg) { + partialProfileDlg = new PartialPasteDlg (Glib::ustring (), parent); + } partialProfileDlg->set_title(M("PROFILEPANEL_PASTEPPASTE")); int i = partialProfileDlg->run(); partialProfileDlg->hide(); @@ -613,6 +628,9 @@ void ProfilePanel::paste_clicked (GdkEventButton* event) if (event->state & Gdk::CONTROL_MASK) // custom.pparams = clipboard.pparams filtered by ( clipboard.pedited & partialPaste.pedited ) { + if(!partialProfileDlg) { + partialProfileDlg = new PartialPasteDlg (Glib::ustring (), parent); + } partialProfileDlg->applyPaste (custom->pparams, !fillMode->get_active() ? custom->pedited : nullptr, &pp, &pe); } else { // custom.pparams = clipboard.pparams filtered by ( clipboard.pedited ) @@ -626,6 +644,9 @@ void ProfilePanel::paste_clicked (GdkEventButton* event) if (event->state & Gdk::CONTROL_MASK) // custom.pparams = clipboard.pparams filtered by ( partialPaste.pedited ) { + if(!partialProfileDlg) { + partialProfileDlg = new PartialPasteDlg (Glib::ustring (), parent); + } partialProfileDlg->applyPaste (custom->pparams, nullptr, &pp, nullptr); } else { // custom.pparams = clipboard.pparams non filtered diff --git a/rtgui/profilepanel.h b/rtgui/profilepanel.h index ddd7133ca..dc07e2006 100644 --- a/rtgui/profilepanel.h +++ b/rtgui/profilepanel.h @@ -66,7 +66,7 @@ protected: ProfileChangeListener* tpc; bool dontupdate; sigc::connection changeconn; - + static Gtk::Window* parent; void changeTo (const rtengine::procparams::PartialProfile* newpp, Glib::ustring profname); public: @@ -79,7 +79,7 @@ public: tpc = ppl; } - static void init (Gtk::Window* parent); + static void init (Gtk::Window* parentWindow); static void cleanup (); void storeCurrentValue(); void updateProfileList (); diff --git a/rtgui/prsharpening.cc b/rtgui/prsharpening.cc index 5e79d078a..94034b471 100644 --- a/rtgui/prsharpening.cc +++ b/rtgui/prsharpening.cc @@ -240,20 +240,20 @@ void PrSharpening::write (ProcParams* pp, ParamsEdited* pedited) } if (pedited) { - pedited->prsharpening.amount = amount->getEditedState (); - pedited->prsharpening.radius = radius->getEditedState (); - pedited->prsharpening.threshold = threshold->getEditedState (); - pedited->prsharpening.edges_radius = eradius->getEditedState (); - pedited->prsharpening.edges_tolerance = etolerance->getEditedState (); + pedited->prsharpening.amount = amount->getEditedState (); + pedited->prsharpening.radius = radius->getEditedState (); + pedited->prsharpening.threshold = threshold->getEditedState (); + pedited->prsharpening.edges_radius = eradius->getEditedState (); + pedited->prsharpening.edges_tolerance = etolerance->getEditedState (); pedited->prsharpening.halocontrol_amount = hcamount->getEditedState (); - pedited->prsharpening.deconvamount = damount->getEditedState (); - pedited->prsharpening.deconvradius = dradius->getEditedState (); - pedited->prsharpening.deconviter = diter->getEditedState (); - pedited->prsharpening.deconvdamping = ddamping->getEditedState (); - pedited->prsharpening.method = method->get_active_row_number() != 2; - pedited->prsharpening.halocontrol = !halocontrol->get_inconsistent(); - pedited->prsharpening.edgesonly = !edgesonly->get_inconsistent(); - pedited->prsharpening.enabled = !get_inconsistent(); + pedited->prsharpening.deconvamount = damount->getEditedState (); + pedited->prsharpening.deconvradius = dradius->getEditedState (); + pedited->prsharpening.deconviter = diter->getEditedState (); + pedited->prsharpening.deconvdamping = ddamping->getEditedState (); + pedited->prsharpening.method = method->get_active_row_number() != 2; + pedited->prsharpening.halocontrol = !halocontrol->get_inconsistent(); + pedited->prsharpening.edgesonly = !edgesonly->get_inconsistent(); + pedited->prsharpening.enabled = !get_inconsistent(); } } @@ -420,13 +420,15 @@ void PrSharpening::halocontrol_toggled () void PrSharpening::method_changed () { - removeIfThere (this, usm, false); - removeIfThere (this, rld, false); + if (!batchMode) { + removeIfThere (this, usm, false); + removeIfThere (this, rld, false); - if (method->get_active_row_number() == 0) { - pack_start (*usm); - } else if (method->get_active_row_number() == 1) { - pack_start (*rld); + if (method->get_active_row_number() == 0) { + pack_start (*usm); + } else if (method->get_active_row_number() == 1) { + pack_start (*rld); + } } if (listener && (multiImage || getEnabled()) ) { @@ -453,6 +455,7 @@ void PrSharpening::setBatchMode (bool batchMode) hcbin->pack_start (*hcbox); removeIfThere (edgebin, edgebox, false); edgebin->pack_start (*edgebox); + pack_start (*rld); radius->showEditedCB (); amount->showEditedCB (); @@ -467,16 +470,30 @@ void PrSharpening::setBatchMode (bool batchMode) method->append (M("GENERAL_UNCHANGED")); } -void PrSharpening::setAdjusterBehavior (bool amountadd) +void PrSharpening::setAdjusterBehavior (bool radiusadd, bool amountadd, bool dampingadd, bool iteradd, bool edgetoladd, bool haloctrladd) { + radius->setAddMode(radiusadd); + dradius->setAddMode(radiusadd); amount->setAddMode(amountadd); damount->setAddMode(amountadd); + ddamping->setAddMode(dampingadd); + diter->setAddMode(iteradd); + eradius->setAddMode(radiusadd); + etolerance->setAddMode(edgetoladd); + hcamount->setAddMode(haloctrladd); } void PrSharpening::trimValues (rtengine::procparams::ProcParams* pp) { + radius->trimValue(pp->prsharpening.radius); + dradius->trimValue(pp->prsharpening.deconvradius); amount->trimValue(pp->prsharpening.amount); damount->trimValue(pp->prsharpening.deconvamount); + ddamping->trimValue(pp->prsharpening.deconvdamping); + diter->trimValue(pp->prsharpening.deconviter); + eradius->trimValue(pp->prsharpening.edges_radius); + etolerance->trimValue(pp->prsharpening.edges_tolerance); + hcamount->trimValue(pp->prsharpening.halocontrol_amount); } diff --git a/rtgui/prsharpening.h b/rtgui/prsharpening.h index 9bf90cc6c..50dc91258 100644 --- a/rtgui/prsharpening.h +++ b/rtgui/prsharpening.h @@ -70,7 +70,7 @@ public: void method_changed (); void adjusterChanged (ThresholdAdjuster* a, int newBottomL, int newTopL, int newBottomR, int newTopR); - void setAdjusterBehavior (bool amountadd); + void setAdjusterBehavior (bool radiusadd, bool amountadd, bool dampingadd, bool iteradd, bool edgetoladd, bool haloctrladd); void trimValues (rtengine::procparams::ProcParams* pp); }; diff --git a/rtgui/resize.cc b/rtgui/resize.cc index 1a87bbe8c..971901b84 100644 --- a/rtgui/resize.cc +++ b/rtgui/resize.cc @@ -620,3 +620,14 @@ void Resize::enabledChanged () } } +void Resize::setAdjusterBehavior (bool scaleadd) +{ + + scale->setAddMode(scaleadd); +} + +void Resize::trimValues (rtengine::procparams::ProcParams* pp) +{ + + scale->trimValue(pp->resize.scale); +} diff --git a/rtgui/resize.h b/rtgui/resize.h index acba5b478..2b2c2ea26 100644 --- a/rtgui/resize.h +++ b/rtgui/resize.h @@ -57,6 +57,9 @@ public: void setDimensions (); void enabledChanged (); + void setAdjusterBehavior (bool scaleadd); + void trimValues (rtengine::procparams::ProcParams* pp); + private: void fitBoxScale (); int getComputedWidth (); diff --git a/rtgui/rtimage.cc b/rtgui/rtimage.cc index 16e8e3286..b24158b00 100644 --- a/rtgui/rtimage.cc +++ b/rtgui/rtimage.cc @@ -28,7 +28,7 @@ namespace { -std::map> pixbufCache; +std::map> pixbufCache; } diff --git a/rtgui/rtwindow.cc b/rtgui/rtwindow.cc index c51d1b7f0..80e481315 100644 --- a/rtgui/rtwindow.cc +++ b/rtgui/rtwindow.cc @@ -18,7 +18,6 @@ */ #include -#include #include "rtwindow.h" #include "options.h" #include "preferences.h" @@ -32,27 +31,27 @@ static gboolean osx_should_quit_cb (GtkosxApplication *app, gpointer data) { RTWindow *rtWin = (RTWindow *)data; - return rtWin->on_delete_event(0); + return rtWin->on_delete_event (0); } static void osx_will_quit_cb (GtkosxApplication *app, gpointer data) { RTWindow *rtWin = (RTWindow *)data; - rtWin->on_delete_event(0); + rtWin->on_delete_event (0); gtk_main_quit (); } -bool RTWindow::osxFileOpenEvent(Glib::ustring path) +bool RTWindow::osxFileOpenEvent (Glib::ustring path) { CacheManager* cm = CacheManager::getInstance(); - Thumbnail* thm = cm->getEntry( path ); + Thumbnail* thm = cm->getEntry ( path ); - if(thm && fpanel) { + if (thm && fpanel) { std::vector entries; - entries.push_back(thm); - fpanel->fileCatalog->openRequested(entries); + entries.push_back (thm); + fpanel->fileCatalog->openRequested (entries); return true; } @@ -69,25 +68,25 @@ osx_open_file_cb (GtkosxApplication *app, gchar *path_, gpointer data) return false; } - Glib::ustring path = Glib::ustring(path_); - Glib::ustring suffix = path.length() > 4 ? path.substr(path.length() - 3) : ""; + Glib::ustring path = Glib::ustring (path_); + Glib::ustring suffix = path.length() > 4 ? path.substr (path.length() - 3) : ""; suffix = suffix.lowercase(); if (suffix == "pp3") { - path = path.substr(0, path.length() - 4); + path = path.substr (0, path.length() - 4); } - return rtWin->osxFileOpenEvent(path); + return rtWin->osxFileOpenEvent (path); } #endif // __APPLE__ RTWindow::RTWindow () - : mainNB(nullptr) - , bpanel(nullptr) - , splash(nullptr) - , btn_fullscreen(nullptr) - , epanel(nullptr) - , fpanel(nullptr) + : mainNB (nullptr) + , bpanel (nullptr) + , splash (nullptr) + , btn_fullscreen (nullptr) + , epanel (nullptr) + , fpanel (nullptr) { cacheMgr->init (); @@ -95,11 +94,11 @@ RTWindow::RTWindow () ProfilePanel::init (this); Glib::ustring fName = "rt-logo-small.png"; - Glib::ustring fullPath = rtengine::findIconAbsolutePath(fName); + Glib::ustring fullPath = rtengine::findIconAbsolutePath (fName); try { set_default_icon_from_file (fullPath); - } catch(Glib::Exception& ex) { + } catch (Glib::Exception& ex) { printf ("%s\n", ex.what().c_str()); } @@ -122,55 +121,57 @@ RTWindow::RTWindow () #endif versionStr = "RawTherapee " + versionString; - set_title_decorated(""); - set_resizable(true); - set_decorated(true); - set_default_size(options.windowWidth, options.windowHeight); - set_modal(false); + set_title_decorated (""); + set_resizable (true); + set_decorated (true); + set_default_size (options.windowWidth, options.windowHeight); + set_modal (false); Gdk::Rectangle lMonitorRect; - get_screen()->get_monitor_geometry(std::min(options.windowMonitor, Gdk::Screen::get_default()->get_n_monitors() - 1), lMonitorRect); + get_screen()->get_monitor_geometry (std::min (options.windowMonitor, Gdk::Screen::get_default()->get_n_monitors() - 1), lMonitorRect); + if (options.windowMaximized) { - move(lMonitorRect.get_x(), lMonitorRect.get_y()); + move (lMonitorRect.get_x(), lMonitorRect.get_y()); maximize(); } else { unmaximize(); - resize(options.windowWidth, options.windowHeight); - if(options.windowX <= lMonitorRect.get_x() + lMonitorRect.get_width() && options.windowY <= lMonitorRect.get_y() + lMonitorRect.get_height()) { - move(options.windowX, options.windowY); + resize (options.windowWidth, options.windowHeight); + + if (options.windowX <= lMonitorRect.get_x() + lMonitorRect.get_width() && options.windowY <= lMonitorRect.get_y() + lMonitorRect.get_height()) { + move (options.windowX, options.windowY); } else { - move(lMonitorRect.get_x(), lMonitorRect.get_y()); + move (lMonitorRect.get_x(), lMonitorRect.get_y()); } } on_delete_has_run = false; is_fullscreen = false; - property_destroy_with_parent().set_value(false); - signal_window_state_event().connect( sigc::mem_fun(*this, &RTWindow::on_window_state_event) ); - signal_key_press_event().connect( sigc::mem_fun(*this, &RTWindow::keyPressed) ); + property_destroy_with_parent().set_value (false); + signal_window_state_event().connect ( sigc::mem_fun (*this, &RTWindow::on_window_state_event) ); + signal_key_press_event().connect ( sigc::mem_fun (*this, &RTWindow::keyPressed) ); - if(simpleEditor) { - epanel = Gtk::manage( new EditorPanel (nullptr) ); + if (simpleEditor) { + epanel = Gtk::manage ( new EditorPanel (nullptr) ); epanel->setParent (this); - epanel->setParentWindow(this); + epanel->setParentWindow (this); add (*epanel); show_all (); pldBridge = nullptr; // No progress listener CacheManager* cm = CacheManager::getInstance(); - Thumbnail* thm = cm->getEntry( argv1 ); + Thumbnail* thm = cm->getEntry ( argv1 ); - if(thm) { + if (thm) { int error; - rtengine::InitialImage *ii = rtengine::InitialImage::load(argv1, thm->getType() == FT_Raw, &error, nullptr); - epanel->open( thm, ii ); + rtengine::InitialImage *ii = rtengine::InitialImage::load (argv1, thm->getType() == FT_Raw, &error, nullptr); + epanel->open ( thm, ii ); } } else { mainNB = Gtk::manage (new Gtk::Notebook ()); mainNB->set_name ("MainNotebook"); mainNB->set_scrollable (true); - mainNB->signal_switch_page().connect_notify( sigc::mem_fun(*this, &RTWindow::on_mainNB_switch_page) ); + mainNB->signal_switch_page().connect_notify ( sigc::mem_fun (*this, &RTWindow::on_mainNB_switch_page) ); // Editor panel fpanel = new FilePanel () ; @@ -178,20 +179,20 @@ RTWindow::RTWindow () // decorate tab Gtk::Grid* fpanelLabelGrid = Gtk::manage (new Gtk::Grid ()); - setExpandAlignProperties(fpanelLabelGrid, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); - Gtk::Label* fpl = Gtk::manage (new Gtk::Label( Glib::ustring(" ") + M("MAIN_FRAME_EDITOR") )); + setExpandAlignProperties (fpanelLabelGrid, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); + Gtk::Label* fpl = Gtk::manage (new Gtk::Label ( Glib::ustring (" ") + M ("MAIN_FRAME_EDITOR") )); if (options.mainNBVertical) { mainNB->set_tab_pos (Gtk::POS_LEFT); fpl->set_angle (90); - fpanelLabelGrid->attach_next_to(*Gtk::manage (new RTImage ("gtk-directory.png")), Gtk::POS_TOP, 1, 1); - fpanelLabelGrid->attach_next_to(*fpl, Gtk::POS_TOP, 1, 1); + fpanelLabelGrid->attach_next_to (*Gtk::manage (new RTImage ("gtk-directory.png")), Gtk::POS_TOP, 1, 1); + fpanelLabelGrid->attach_next_to (*fpl, Gtk::POS_TOP, 1, 1); } else { - fpanelLabelGrid->attach_next_to(*Gtk::manage (new RTImage ("gtk-directory.png")), Gtk::POS_RIGHT, 1, 1); - fpanelLabelGrid->attach_next_to(*fpl, Gtk::POS_RIGHT, 1, 1); + fpanelLabelGrid->attach_next_to (*Gtk::manage (new RTImage ("gtk-directory.png")), Gtk::POS_RIGHT, 1, 1); + fpanelLabelGrid->attach_next_to (*fpl, Gtk::POS_RIGHT, 1, 1); } - fpanelLabelGrid->set_tooltip_markup (M("MAIN_FRAME_FILEBROWSER_TOOLTIP")); + fpanelLabelGrid->set_tooltip_markup (M ("MAIN_FRAME_FILEBROWSER_TOOLTIP")); fpanelLabelGrid->show_all (); mainNB->append_page (*fpanel, *fpanelLabelGrid); @@ -200,16 +201,16 @@ RTWindow::RTWindow () bpanel = Gtk::manage ( new BatchQueuePanel (fpanel->fileCatalog) ); // decorate tab, the label is unimportant since its updated in batchqueuepanel anyway - Gtk::Label* lbq = Gtk::manage ( new Gtk::Label (M("MAIN_FRAME_BATCHQUEUE")) ); + Gtk::Label* lbq = Gtk::manage ( new Gtk::Label (M ("MAIN_FRAME_BATCHQUEUE")) ); if (options.mainNBVertical) { - lbq->set_angle(90); + lbq->set_angle (90); } mainNB->append_page (*bpanel, *lbq); - if(isSingleTabMode()) { + if (isSingleTabMode()) { createSetmEditor(); } @@ -225,46 +226,46 @@ RTWindow::RTWindow () //Gtk::LinkButton* rtWeb = Gtk::manage (new Gtk::LinkButton ("http://rawtherapee.com")); // unused... but fail to be linked anyway !? //Gtk::Button* preferences = Gtk::manage (new Gtk::Button (M("MAIN_BUTTON_PREFERENCES")+"...")); Gtk::Button* preferences = Gtk::manage (new Gtk::Button ()); - setExpandAlignProperties(preferences, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); - preferences->set_image (*Gtk::manage(new RTImage ("gtk-preferences.png"))); - preferences->set_tooltip_markup (M("MAIN_BUTTON_PREFERENCES")); - preferences->signal_clicked().connect( sigc::mem_fun(*this, &RTWindow::showPreferences) ); + setExpandAlignProperties (preferences, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); + preferences->set_image (*Gtk::manage (new RTImage ("gtk-preferences.png"))); + preferences->set_tooltip_markup (M ("MAIN_BUTTON_PREFERENCES")); + preferences->signal_clicked().connect ( sigc::mem_fun (*this, &RTWindow::showPreferences) ); //btn_fullscreen = Gtk::manage( new Gtk::Button(M("MAIN_BUTTON_FULLSCREEN"))); - btn_fullscreen = Gtk::manage( new Gtk::Button()); - setExpandAlignProperties(btn_fullscreen, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); - btn_fullscreen->set_tooltip_markup (M("MAIN_BUTTON_FULLSCREEN")); + btn_fullscreen = Gtk::manage ( new Gtk::Button()); + setExpandAlignProperties (btn_fullscreen, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); + btn_fullscreen->set_tooltip_markup (M ("MAIN_BUTTON_FULLSCREEN")); btn_fullscreen->set_image (*iFullscreen); - btn_fullscreen->signal_clicked().connect( sigc::mem_fun(*this, &RTWindow::toggle_fullscreen) ); - setExpandAlignProperties(&prProgBar, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); - prProgBar.set_show_text(true); + btn_fullscreen->signal_clicked().connect ( sigc::mem_fun (*this, &RTWindow::toggle_fullscreen) ); + setExpandAlignProperties (&prProgBar, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); + prProgBar.set_show_text (true); Gtk::Grid* actionGrid = Gtk::manage (new Gtk::Grid ()); - actionGrid->set_row_spacing(2); - actionGrid->set_column_spacing(2); + actionGrid->set_row_spacing (2); + actionGrid->set_column_spacing (2); - setExpandAlignProperties(actionGrid, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); + setExpandAlignProperties (actionGrid, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); if (options.mainNBVertical) { - prProgBar.set_orientation(Gtk::ORIENTATION_VERTICAL); - prProgBar.set_inverted(true); - actionGrid->set_orientation(Gtk::ORIENTATION_VERTICAL); - actionGrid->attach_next_to(prProgBar, Gtk::POS_BOTTOM, 1, 1); - actionGrid->attach_next_to(*preferences, Gtk::POS_BOTTOM, 1, 1); - actionGrid->attach_next_to(*btn_fullscreen, Gtk::POS_BOTTOM, 1, 1); - mainNB->set_action_widget(actionGrid, Gtk::PACK_END); + prProgBar.set_orientation (Gtk::ORIENTATION_VERTICAL); + prProgBar.set_inverted (true); + actionGrid->set_orientation (Gtk::ORIENTATION_VERTICAL); + actionGrid->attach_next_to (prProgBar, Gtk::POS_BOTTOM, 1, 1); + actionGrid->attach_next_to (*preferences, Gtk::POS_BOTTOM, 1, 1); + actionGrid->attach_next_to (*btn_fullscreen, Gtk::POS_BOTTOM, 1, 1); + mainNB->set_action_widget (actionGrid, Gtk::PACK_END); } else { - prProgBar.set_orientation(Gtk::ORIENTATION_HORIZONTAL); - actionGrid->set_orientation(Gtk::ORIENTATION_HORIZONTAL); - actionGrid->attach_next_to(prProgBar, Gtk::POS_RIGHT, 1, 1); - actionGrid->attach_next_to(*preferences, Gtk::POS_RIGHT, 1, 1); - actionGrid->attach_next_to(*btn_fullscreen, Gtk::POS_RIGHT, 1, 1); - mainNB->set_action_widget(actionGrid, Gtk::PACK_END); + prProgBar.set_orientation (Gtk::ORIENTATION_HORIZONTAL); + actionGrid->set_orientation (Gtk::ORIENTATION_HORIZONTAL); + actionGrid->attach_next_to (prProgBar, Gtk::POS_RIGHT, 1, 1); + actionGrid->attach_next_to (*preferences, Gtk::POS_RIGHT, 1, 1); + actionGrid->attach_next_to (*btn_fullscreen, Gtk::POS_RIGHT, 1, 1); + mainNB->set_action_widget (actionGrid, Gtk::PACK_END); } actionGrid->show_all(); - pldBridge = new PLDBridge(static_cast(this)); + pldBridge = new PLDBridge (static_cast (this)); add (*mainNB); show_all (); @@ -272,9 +273,10 @@ RTWindow::RTWindow () bpanel->init (this); if (!argv1.empty() && !remote) { - Thumbnail* thm = cacheMgr->getEntry(argv1); + Thumbnail* thm = cacheMgr->getEntry (argv1); + if (thm) { - fpanel->fileCatalog->openRequested({thm}); + fpanel->fileCatalog->openRequested ({thm}); } } } @@ -282,7 +284,7 @@ RTWindow::RTWindow () RTWindow::~RTWindow() { - if(!simpleEditor) { + if (!simpleEditor) { delete pldBridge; } @@ -300,7 +302,7 @@ void RTWindow::on_realize () { Gtk::Window::on_realize (); - if( fpanel ) { + if ( fpanel ) { fpanel->setAspect(); } @@ -308,76 +310,68 @@ void RTWindow::on_realize () epanel->setAspect(); } - mainWindowCursorManager.init(get_window()); + mainWindowCursorManager.init (get_window()); // Display release notes only if new major version. // Pattern matches "5.1" from "5.1-23-g12345678" - std::string vs[] = {versionString, options.version}; - std::regex pat("(^[0-9.]+).*"); - std::smatch sm; + const std::string vs[] = {versionString, options.version}; std::vector vMajor; - for (const auto &v : vs) { - if (std::regex_match(v, sm, pat)) { - if (sm.size() == 2) { - std::ssub_match smsub = sm[1]; - vMajor.push_back(smsub.str()); - } - } + + for (const auto& v : vs) { + vMajor.emplace_back(v, 0, v.find_first_not_of("0123456789.")); } - if (vMajor.size() == 2) { - if (vMajor[0] != vMajor[1]) { + if (vMajor.size() == 2 && vMajor[0] != vMajor[1]) { + // Update the version parameter with the right value + options.version = versionString; - // Update the version parameter with the right value - options.version = versionString; + splash = new Splash (*this); + splash->set_transient_for (*this); + splash->signal_delete_event().connect ( sigc::mem_fun (*this, &RTWindow::splashClosed) ); - splash = new Splash (*this); - splash->set_transient_for (*this); - splash->signal_delete_event().connect( sigc::mem_fun(*this, &RTWindow::splashClosed) ); - - if (splash->hasReleaseNotes()) { - splash->showReleaseNotes(); - splash->show (); - } else { - delete splash; - splash = nullptr; - } + if (splash->hasReleaseNotes()) { + splash->showReleaseNotes(); + splash->show (); + } else { + delete splash; + splash = nullptr; } } } -bool RTWindow::on_configure_event(GdkEventConfigure* event) +bool RTWindow::on_configure_event (GdkEventConfigure* event) { if (!is_maximized() && is_visible()) { - get_size(options.windowWidth, options.windowHeight); + get_size (options.windowWidth, options.windowHeight); get_position (options.windowX, options.windowY); } - return Gtk::Widget::on_configure_event(event); + return Gtk::Widget::on_configure_event (event); } -bool RTWindow::on_window_state_event(GdkEventWindowState* event) +bool RTWindow::on_window_state_event (GdkEventWindowState* event) { if (event->changed_mask & GDK_WINDOW_STATE_MAXIMIZED) { options.windowMaximized = event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED; } - return Gtk::Widget::on_window_state_event(event); + + return Gtk::Widget::on_window_state_event (event); } -void RTWindow::on_mainNB_switch_page(Gtk::Widget* widget, guint page_num) +void RTWindow::on_mainNB_switch_page (Gtk::Widget* widget, guint page_num) { - if(!on_delete_has_run) { - if(isEditorPanel(page_num)) { + if (!on_delete_has_run) { + if (isEditorPanel (page_num)) { if (isSingleTabMode() && epanel) { MoveFileBrowserToEditor(); } - EditorPanel *ep = static_cast(mainNB->get_nth_page(page_num)); + EditorPanel *ep = static_cast (mainNB->get_nth_page (page_num)); ep->setAspect(); if (!isSingleTabMode()) { if (filesEdited.size() > 0) { - set_title_decorated(ep->getFileName()); + set_title_decorated (ep->getFileName()); } } } else { @@ -387,7 +381,7 @@ void RTWindow::on_mainNB_switch_page(Gtk::Widget* widget, guint page_num) epanel->saveProfile(); // Moving the FileBrowser only if the user has switched to the FileBrowser tab - if (mainNB->get_nth_page(page_num) == fpanel) { + if (mainNB->get_nth_page (page_num) == fpanel) { MoveFileBrowserToMain(); } } @@ -398,32 +392,32 @@ void RTWindow::on_mainNB_switch_page(Gtk::Widget* widget, guint page_num) void RTWindow::addEditorPanel (EditorPanel* ep, const std::string &name) { if (options.multiDisplayMode > 0) { - EditWindow * wndEdit = EditWindow::getInstance(this); + EditWindow * wndEdit = EditWindow::getInstance (this); wndEdit->show(); - wndEdit->addEditorPanel(ep, name); + wndEdit->addEditorPanel (ep, name); wndEdit->toFront(); } else { ep->setParent (this); - ep->setParentWindow(this); + ep->setParentWindow (this); // construct closeable tab for the image Gtk::Grid* titleGrid = Gtk::manage (new Gtk::Grid ()); titleGrid->set_tooltip_markup (name); - RTImage *closebimg = Gtk::manage(new RTImage ("gtk-close.png")); + RTImage *closebimg = Gtk::manage (new RTImage ("gtk-close.png")); Gtk::Button* closeb = Gtk::manage (new Gtk::Button ()); closeb->set_name ("CloseButton"); closeb->add (*closebimg); closeb->set_relief (Gtk::RELIEF_NONE); closeb->set_focus_on_click (false); - closeb->signal_clicked().connect( sigc::bind (sigc::mem_fun(*this, &RTWindow::remEditorPanel) , ep)); + closeb->signal_clicked().connect ( sigc::bind (sigc::mem_fun (*this, &RTWindow::remEditorPanel), ep)); - titleGrid->attach_next_to(*Gtk::manage (new RTImage ("rtwindow.png")), Gtk::POS_RIGHT, 1, 1); - titleGrid->attach_next_to(*Gtk::manage (new Gtk::Label (Glib::path_get_basename (name))), Gtk::POS_RIGHT, 1, 1); - titleGrid->attach_next_to(*closeb, Gtk::POS_RIGHT, 1, 1); + titleGrid->attach_next_to (*Gtk::manage (new RTImage ("rtwindow.png")), Gtk::POS_RIGHT, 1, 1); + titleGrid->attach_next_to (*Gtk::manage (new Gtk::Label (Glib::path_get_basename (name))), Gtk::POS_RIGHT, 1, 1); + titleGrid->attach_next_to (*closeb, Gtk::POS_RIGHT, 1, 1); titleGrid->show_all (); //GTK318 #if GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION < 20 - titleGrid->set_column_spacing(2); + titleGrid->set_column_spacing (2); #endif //GTK318 @@ -432,11 +426,11 @@ void RTWindow::addEditorPanel (EditorPanel* ep, const std::string &name) mainNB->set_current_page (mainNB->page_num (*ep)); mainNB->set_tab_reorderable (*ep, true); - set_title_decorated(name); + set_title_decorated (name); epanels[ name ] = ep; filesEdited.insert ( name ); fpanel->refreshEditedState (filesEdited); - ep->tbTopPanel_1_visible(false); //hide the toggle Top Panel button + ep->tbTopPanel_1_visible (false); //hide the toggle Top Panel button } } @@ -447,8 +441,8 @@ void RTWindow::remEditorPanel (EditorPanel* ep) } if (options.multiDisplayMode > 0) { - EditWindow * wndEdit = EditWindow::getInstance(this); - wndEdit->remEditorPanel(ep); + EditWindow * wndEdit = EditWindow::getInstance (this); + wndEdit->remEditorPanel (ep); } else { bool queueHadFocus = (mainNB->get_current_page() == mainNB->page_num (*bpanel)); epanels.erase (ep->getFileName()); @@ -457,37 +451,37 @@ void RTWindow::remEditorPanel (EditorPanel* ep) mainNB->remove_page (*ep); - if (!isEditorPanel(mainNB->get_current_page())) { - if(!queueHadFocus) { + if (!isEditorPanel (mainNB->get_current_page())) { + if (!queueHadFocus) { mainNB->set_current_page (mainNB->page_num (*fpanel)); } - set_title_decorated(""); + set_title_decorated (""); } else { - EditorPanel* ep = static_cast(mainNB->get_nth_page (mainNB->get_current_page())); - set_title_decorated(ep->getFileName()); + EditorPanel* ep = static_cast (mainNB->get_nth_page (mainNB->get_current_page())); + set_title_decorated (ep->getFileName()); } // TODO: ask what to do: close & apply, close & apply selection, close & revert, cancel } } -bool RTWindow::selectEditorPanel(const std::string &name) +bool RTWindow::selectEditorPanel (const std::string &name) { if (options.multiDisplayMode > 0) { - EditWindow * wndEdit = EditWindow::getInstance(this); + EditWindow * wndEdit = EditWindow::getInstance (this); - if (wndEdit->selectEditorPanel(name)) { - set_title_decorated(name); + if (wndEdit->selectEditorPanel (name)) { + set_title_decorated (name); wndEdit->toFront(); return true; } } else { - std::map::iterator iep = epanels.find(name); + std::map::iterator iep = epanels.find (name); if (iep != epanels.end()) { mainNB->set_current_page (mainNB->page_num (*iep->second)); - set_title_decorated(name); + set_title_decorated (name); return true; } else { //set_title_decorated(name); @@ -521,12 +515,12 @@ bool RTWindow::keyPressed (GdkEventKey* event) #endif if (try_quit) { - if (!on_delete_event(nullptr)) { + if (!on_delete_event (nullptr)) { gtk_main_quit(); } } - if(event->keyval == GDK_KEY_F11) { + if (event->keyval == GDK_KEY_F11) { toggle_fullscreen(); } @@ -537,40 +531,40 @@ bool RTWindow::keyPressed (GdkEventKey* event) }; if (ctrl) { - switch(event->keyval) { - case GDK_KEY_F2: // file browser panel - mainNB->set_current_page (mainNB->page_num (*fpanel)); - return true; - - case GDK_KEY_F3: // batch queue panel - mainNB->set_current_page (mainNB->page_num (*bpanel)); - return true; - - case GDK_KEY_F4: //single tab mode, editor panel - if (isSingleTabMode() && epanel) { - mainNB->set_current_page (mainNB->page_num (*epanel)); - } - - return true; - - case GDK_KEY_w: //multi-tab mode, close editor panel - if (!isSingleTabMode() && - mainNB->get_current_page() != mainNB->page_num(*fpanel) && - mainNB->get_current_page() != mainNB->page_num(*bpanel)) { - - EditorPanel* ep = static_cast(mainNB->get_nth_page (mainNB->get_current_page())); - remEditorPanel (ep); + switch (event->keyval) { + case GDK_KEY_F2: // file browser panel + mainNB->set_current_page (mainNB->page_num (*fpanel)); return true; - } + + case GDK_KEY_F3: // batch queue panel + mainNB->set_current_page (mainNB->page_num (*bpanel)); + return true; + + case GDK_KEY_F4: //single tab mode, editor panel + if (isSingleTabMode() && epanel) { + mainNB->set_current_page (mainNB->page_num (*epanel)); + } + + return true; + + case GDK_KEY_w: //multi-tab mode, close editor panel + if (!isSingleTabMode() && + mainNB->get_current_page() != mainNB->page_num (*fpanel) && + mainNB->get_current_page() != mainNB->page_num (*bpanel)) { + + EditorPanel* ep = static_cast (mainNB->get_nth_page (mainNB->get_current_page())); + remEditorPanel (ep); + return true; + } } } - if (mainNB->get_current_page() == mainNB->page_num(*fpanel)) { + if (mainNB->get_current_page() == mainNB->page_num (*fpanel)) { return fpanel->handleShortcutKey (event); - } else if (mainNB->get_current_page() == mainNB->page_num(*bpanel)) { + } else if (mainNB->get_current_page() == mainNB->page_num (*bpanel)) { return bpanel->handleShortcutKey (event); } else { - EditorPanel* ep = static_cast(mainNB->get_nth_page (mainNB->get_current_page())); + EditorPanel* ep = static_cast (mainNB->get_nth_page (mainNB->get_current_page())); return ep->handleShortcutKey (event); } @@ -581,7 +575,7 @@ void RTWindow::addBatchQueueJob (BatchQueueEntry* bqe, bool head) { std::vector entries; - entries.push_back(bqe); + entries.push_back (bqe); bpanel->addBatchQueueJobs (entries, head); fpanel->queue_draw (); } @@ -593,7 +587,7 @@ void RTWindow::addBatchQueueJobs (std::vector &entries) fpanel->queue_draw (); } -bool RTWindow::on_delete_event(GdkEventAny* event) +bool RTWindow::on_delete_event (GdkEventAny* event) { if (on_delete_has_run) { @@ -608,14 +602,14 @@ bool RTWindow::on_delete_event(GdkEventAny* event) if (isSingleTabMode() || simpleEditor) { isProcessing = epanel->getIsProcessing(); } else if (options.multiDisplayMode > 0) { - editWindow = EditWindow::getInstance(this, false); + editWindow = EditWindow::getInstance (this, false); isProcessing = editWindow->isProcessing(); } else { int pageCount = mainNB->get_n_pages(); for (int i = 0; i < pageCount && !isProcessing; i++) { - if(isEditorPanel(i)) { - isProcessing |= (static_cast(mainNB->get_nth_page(i)))->getIsProcessing(); + if (isEditorPanel (i)) { + isProcessing |= (static_cast (mainNB->get_nth_page (i)))->getIsProcessing(); } } } @@ -624,11 +618,11 @@ bool RTWindow::on_delete_event(GdkEventAny* event) return true; } - if( fpanel ) { + if ( fpanel ) { fpanel->saveOptions (); } - if( bpanel ) { + if ( bpanel ) { bpanel->saveOptions (); } @@ -644,7 +638,7 @@ bool RTWindow::on_delete_event(GdkEventAny* event) // Look at the active panel first, if any, otherwise look at the first one (sorted on the filename) int page = mainNB->get_current_page(); - Gtk::Widget *w = mainNB->get_nth_page(page); + Gtk::Widget *w = mainNB->get_nth_page (page); bool optionsWritten = false; for (std::map::iterator i = epanels.begin(); i != epanels.end(); ++i) { @@ -667,19 +661,55 @@ bool RTWindow::on_delete_event(GdkEventAny* event) ProfilePanel::cleanup(); if (!options.windowMaximized) { - get_size(options.windowWidth, options.windowHeight); + get_size (options.windowWidth, options.windowHeight); get_position (options.windowX, options.windowY); } - options.windowMonitor = get_screen()->get_monitor_at_window(get_window()); + options.windowMonitor = get_screen()->get_monitor_at_window (get_window()); + + try { + Options::save (); + } catch (Options::Error &e) { + Gtk::MessageDialog msgd (getToplevelWindow (this), e.get_msg(), true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_CLOSE, true); + msgd.run(); + } - Options::save (); hide(); on_delete_has_run = true; return false; } + +void RTWindow::writeToolExpandedStatus (std::vector &tpOpen) +{ + if ((isSingleTabMode() || gimpPlugin) && epanel->isRealized()) { + epanel->writeToolExpandedStatus (tpOpen); + } else { + // Storing the options of the last EditorPanel before Gtk destroys everything + // Look at the active panel first, if any, otherwise look at the first one (sorted on the filename) + if (epanels.size()) { + int page = mainNB->get_current_page(); + Gtk::Widget *w = mainNB->get_nth_page (page); + bool optionsWritten = false; + + for (std::map::iterator i = epanels.begin(); i != epanels.end(); ++i) { + if (i->second == w) { + i->second->writeToolExpandedStatus (tpOpen); + optionsWritten = true; + } + } + + if (!optionsWritten) { + // fallback solution: save the options of the first editor panel + std::map::iterator i = epanels.begin(); + i->second->writeToolExpandedStatus (tpOpen); + } + } + } +} + + void RTWindow::showPreferences () { Preferences *pref = new Preferences (this); @@ -687,11 +717,13 @@ void RTWindow::showPreferences () delete pref; fpanel->optionsChanged (); + if (epanel) { - epanel->defaultMonitorProfileChanged(options.rtSettings.monitorProfile, options.rtSettings.autoMonitorProfile); + epanel->defaultMonitorProfileChanged (options.rtSettings.monitorProfile, options.rtSettings.autoMonitorProfile); } + for (const auto &p : epanels) { - p.second->defaultMonitorProfileChanged(options.rtSettings.monitorProfile, options.rtSettings.autoMonitorProfile); + p.second->defaultMonitorProfileChanged (options.rtSettings.monitorProfile, options.rtSettings.autoMonitorProfile); } } @@ -724,7 +756,7 @@ void RTWindow::toggle_fullscreen () if (btn_fullscreen) { //btn_fullscreen->set_label(M("MAIN_BUTTON_FULLSCREEN")); - btn_fullscreen->set_tooltip_markup(M("MAIN_BUTTON_FULLSCREEN")); + btn_fullscreen->set_tooltip_markup (M ("MAIN_BUTTON_FULLSCREEN")); btn_fullscreen->set_image (*iFullscreen); } } else { @@ -733,7 +765,7 @@ void RTWindow::toggle_fullscreen () if (btn_fullscreen) { //btn_fullscreen->set_label(M("MAIN_BUTTON_UNFULLSCREEN")); - btn_fullscreen->set_tooltip_markup(M("MAIN_BUTTON_UNFULLSCREEN")); + btn_fullscreen->set_tooltip_markup (M ("MAIN_BUTTON_UNFULLSCREEN")); btn_fullscreen->set_image (*iFullscreen_exit); } } @@ -756,50 +788,51 @@ void RTWindow::SetMainCurrent() void RTWindow::MoveFileBrowserToMain() { - if( fpanel->ribbonPane->get_children().empty()) { + if ( fpanel->ribbonPane->get_children().empty()) { FileCatalog *fCatalog = fpanel->fileCatalog; - epanel->catalogPane->remove(*fCatalog); - fpanel->ribbonPane->add(*fCatalog); - fCatalog->enableTabMode(false); - fCatalog->tbLeftPanel_1_visible(true); - fCatalog->tbRightPanel_1_visible(true); + epanel->catalogPane->remove (*fCatalog); + fpanel->ribbonPane->add (*fCatalog); + fCatalog->enableTabMode (false); + fCatalog->tbLeftPanel_1_visible (true); + fCatalog->tbRightPanel_1_visible (true); } } void RTWindow::MoveFileBrowserToEditor() { - if(epanel->catalogPane->get_children().empty() ) { + if (epanel->catalogPane->get_children().empty() ) { FileCatalog *fCatalog = fpanel->fileCatalog; - fpanel->ribbonPane->remove(*fCatalog); + fpanel->ribbonPane->remove (*fCatalog); fCatalog->disableInspector(); - epanel->catalogPane->add(*fCatalog); - epanel->showTopPanel(options.editorFilmStripOpened); - fCatalog->enableTabMode(true); + epanel->catalogPane->add (*fCatalog); + epanel->showTopPanel (options.editorFilmStripOpened); + fCatalog->enableTabMode (true); fCatalog->refreshHeight(); - fCatalog->tbLeftPanel_1_visible(false); - fCatalog->tbRightPanel_1_visible(false); + fCatalog->tbLeftPanel_1_visible (false); + fCatalog->tbRightPanel_1_visible (false); } } -void RTWindow::updateProfiles(const Glib::ustring &printerProfile, rtengine::RenderingIntent printerIntent, bool printerBPC) +void RTWindow::updateProfiles (const Glib::ustring &printerProfile, rtengine::RenderingIntent printerIntent, bool printerBPC) { - if(epanel) { - epanel->updateProfiles(printerProfile, printerIntent, printerBPC); + if (epanel) { + epanel->updateProfiles (printerProfile, printerIntent, printerBPC); } - for(auto panel : epanels) { - panel.second->updateProfiles(printerProfile, printerIntent, printerBPC); + for (auto panel : epanels) { + panel.second->updateProfiles (printerProfile, printerIntent, printerBPC); } } void RTWindow::updateTPVScrollbar (bool hide) { fpanel->updateTPVScrollbar (hide); - if(epanel) { + + if (epanel) { epanel->updateTPVScrollbar (hide); } - for(auto panel : epanels) { + for (auto panel : epanels) { panel.second->updateTPVScrollbar (hide); } } @@ -807,11 +840,12 @@ void RTWindow::updateTPVScrollbar (bool hide) void RTWindow::updateTabsUsesIcons (bool useIcons) { fpanel->updateTabsUsesIcons (useIcons); - if(epanel) { + + if (epanel) { epanel->updateTabsUsesIcons (useIcons); } - for(auto panel : epanels) { + for (auto panel : epanels) { panel.second->updateTabsUsesIcons (useIcons); } } @@ -828,22 +862,23 @@ void RTWindow::updateFBToolBarVisibility (bool showFilmStripToolBar) void RTWindow::updateHistogramPosition (int oldPosition, int newPosition) { - if(epanel) { + if (epanel) { epanel->updateHistogramPosition (oldPosition, newPosition); } - for(auto panel : epanels) { + + for (auto panel : epanels) { panel.second->updateHistogramPosition (oldPosition, newPosition); } } -bool RTWindow::splashClosed(GdkEventAny* event) +bool RTWindow::splashClosed (GdkEventAny* event) { delete splash; splash = nullptr; return true; } -void RTWindow::set_title_decorated(Glib::ustring fname) +void RTWindow::set_title_decorated (Glib::ustring fname) { Glib::ustring subtitle; @@ -851,7 +886,7 @@ void RTWindow::set_title_decorated(Glib::ustring fname) subtitle = " - " + fname; } - set_title(versionStr + subtitle); + set_title (versionStr + subtitle); } void RTWindow::closeOpenEditors() @@ -859,36 +894,36 @@ void RTWindow::closeOpenEditors() std::map::const_iterator itr; itr = epanels.begin(); - while(itr != epanels.end()) { - remEditorPanel((*itr).second); + while (itr != epanels.end()) { + remEditorPanel ((*itr).second); itr = epanels.begin(); } } -bool RTWindow::isEditorPanel(Widget* panel) +bool RTWindow::isEditorPanel (Widget* panel) { return (panel != bpanel) && (panel != fpanel); } -bool RTWindow::isEditorPanel(guint pageNum) +bool RTWindow::isEditorPanel (guint pageNum) { - return isEditorPanel(mainNB->get_nth_page(pageNum)); + return isEditorPanel (mainNB->get_nth_page (pageNum)); } -void RTWindow::setEditorMode(bool tabbedUI) +void RTWindow::setEditorMode (bool tabbedUI) { MoveFileBrowserToMain(); closeOpenEditors(); SetMainCurrent(); - if(tabbedUI) { - mainNB->remove_page(*epanel); + if (tabbedUI) { + mainNB->remove_page (*epanel); epanel = nullptr; - set_title_decorated(""); + set_title_decorated (""); } else { createSetmEditor(); epanel->show_all(); - set_title_decorated(""); + set_title_decorated (""); } } @@ -897,25 +932,25 @@ void RTWindow::createSetmEditor() // Editor panel, single-tab mode only epanel = Gtk::manage ( new EditorPanel (fpanel) ); epanel->setParent (this); - epanel->setParentWindow(this); + epanel->setParentWindow (this); // decorate tab Gtk::Grid* const editorLabelGrid = Gtk::manage (new Gtk::Grid ()); - setExpandAlignProperties(editorLabelGrid, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); - Gtk::Label* const el = Gtk::manage (new Gtk::Label( Glib::ustring(" ") + M("MAIN_FRAME_EDITOR") )); + setExpandAlignProperties (editorLabelGrid, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); + Gtk::Label* const el = Gtk::manage (new Gtk::Label ( Glib::ustring (" ") + M ("MAIN_FRAME_EDITOR") )); const auto pos = options.mainNBVertical ? Gtk::POS_TOP : Gtk::POS_RIGHT; if (options.mainNBVertical) { - el->set_angle(90); + el->set_angle (90); } - editorLabelGrid->attach_next_to(*Gtk::manage (new RTImage ("rt-logo-small.png")), pos, 1, 1); - editorLabelGrid->attach_next_to(*el, pos, 1, 1); + editorLabelGrid->attach_next_to (*Gtk::manage (new RTImage ("rt-logo-small.png")), pos, 1, 1); + editorLabelGrid->attach_next_to (*el, pos, 1, 1); - editorLabelGrid->set_tooltip_markup (M("MAIN_FRAME_EDITOR_TOOLTIP")); + editorLabelGrid->set_tooltip_markup (M ("MAIN_FRAME_EDITOR_TOOLTIP")); editorLabelGrid->show_all (); - epanel->tbTopPanel_1_visible(true); //show the toggle Top Panel button + epanel->tbTopPanel_1_visible (true); //show the toggle Top Panel button mainNB->append_page (*epanel, *editorLabelGrid); } diff --git a/rtgui/rtwindow.h b/rtgui/rtwindow.h index faad5f849..9c1699bcf 100644 --- a/rtgui/rtwindow.h +++ b/rtgui/rtwindow.h @@ -50,15 +50,15 @@ private: bool isSingleTabMode() { - return !options.tabbedUI && !(options.multiDisplayMode > 0); + return !options.tabbedUI && ! (options.multiDisplayMode > 0); }; - void findVerNumbers(int* numbers, Glib::ustring versionStr); + void findVerNumbers (int* numbers, Glib::ustring versionStr); - bool on_expose_event_epanel(GdkEventExpose* event); - bool on_expose_event_fpanel(GdkEventExpose* event); - bool splashClosed(GdkEventAny* event); - bool isEditorPanel(Widget* panel); - bool isEditorPanel(guint pageNum); + bool on_expose_event_epanel (GdkEventExpose* event); + bool on_expose_event_fpanel (GdkEventExpose* event); + bool splashClosed (GdkEventAny* event); + bool isEditorPanel (Widget* panel); + bool isEditorPanel (guint pageNum); Glib::ustring versionStr; #if defined(__APPLE__) @@ -70,20 +70,20 @@ public: ~RTWindow(); #if defined(__APPLE__) - bool osxFileOpenEvent(Glib::ustring path); + bool osxFileOpenEvent (Glib::ustring path); #endif void addEditorPanel (EditorPanel* ep, const std::string &name); void remEditorPanel (EditorPanel* ep); - bool selectEditorPanel(const std::string &name); + bool selectEditorPanel (const std::string &name); void addBatchQueueJob (BatchQueueEntry* bqe, bool head = false); void addBatchQueueJobs (std::vector &entries); bool keyPressed (GdkEventKey* event); - bool on_configure_event(GdkEventConfigure* event); - bool on_delete_event(GdkEventAny* event); - bool on_window_state_event(GdkEventWindowState* event); - void on_mainNB_switch_page(Gtk::Widget* widget, guint page_num); + bool on_configure_event (GdkEventConfigure* event); + bool on_delete_event (GdkEventAny* event); + bool on_window_state_event (GdkEventWindowState* event); + void on_mainNB_switch_page (Gtk::Widget* widget, guint page_num); void showPreferences (); void on_realize (); @@ -115,10 +115,12 @@ public: { return is_fullscreen; } - void set_title_decorated(Glib::ustring fname); + void set_title_decorated (Glib::ustring fname); void closeOpenEditors(); - void setEditorMode(bool tabbedUI); + void setEditorMode (bool tabbedUI); void createSetmEditor(); + + void writeToolExpandedStatus (std::vector &tpOpen); }; #endif diff --git a/rtgui/saveasdlg.cc b/rtgui/saveasdlg.cc index 865373b60..1818d748a 100644 --- a/rtgui/saveasdlg.cc +++ b/rtgui/saveasdlg.cc @@ -299,7 +299,7 @@ void SaveAsDialog::formatChanged (Glib::ustring f) void SaveAsDialog::setInitialFileName (Glib::ustring fname) { - + this->fname = fname; fchooser->set_current_name(fname); } diff --git a/rtgui/saveformatpanel.cc b/rtgui/saveformatpanel.cc index cc4088741..13e687595 100644 --- a/rtgui/saveformatpanel.cc +++ b/rtgui/saveformatpanel.cc @@ -82,15 +82,6 @@ SaveFormatPanel::SaveFormatPanel () : listener (nullptr) jpegOpts->attach(*jpegSubSamp, 1, 1, 1, 1); jpegOpts->show_all (); - // --------------------- PNG OPTIONS - - - pngCompr = new Adjuster (M("SAVEDLG_PNGCOMPR"), 0, 6, 1, 6); - setExpandAlignProperties(pngCompr, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - pngCompr->setAdjusterListener (this); - pngCompr->show_all (); - - // --------------------- TIFF OPTIONS @@ -113,13 +104,11 @@ SaveFormatPanel::SaveFormatPanel () : listener (nullptr) attach (*hb1, 0, 0, 1, 1); attach (*jpegOpts, 0, 1, 1, 1); attach (*tiffUncompressed, 0, 2, 1, 1); - attach (*pngCompr, 0, 3, 1, 1); attach (*savesPP, 0, 4, 1, 2); } SaveFormatPanel::~SaveFormatPanel () { delete jpegQual; - delete pngCompr; delete tiffUncompressed; } @@ -143,7 +132,6 @@ void SaveFormatPanel::init (SaveFormat &sf) jpegSubSamp->set_active (sf.jpegSubSamp - 1); - pngCompr->setValue (sf.pngCompression); jpegQual->setValue (sf.jpegQuality); savesPP->set_active (sf.saveParams); tiffUncompressed->set_active (sf.tiffUncompressed); @@ -170,7 +158,6 @@ SaveFormat SaveFormatPanel::getFormat () sf.tiffBits = 8; } - sf.pngCompression = (int) pngCompr->getValue (); sf.jpegQuality = (int) jpegQual->getValue (); sf.jpegSubSamp = jpegSubSamp->get_active_row_number() + 1; sf.tiffUncompressed = tiffUncompressed->get_active(); @@ -192,15 +179,12 @@ void SaveFormatPanel::formatChanged () if (fr == "jpg") { jpegOpts->show_all(); tiffUncompressed->hide(); - pngCompr->hide(); } else if (fr == "png") { jpegOpts->hide(); tiffUncompressed->hide(); - pngCompr->show_all(); } else if (fr == "tif") { jpegOpts->hide(); tiffUncompressed->show_all(); - pngCompr->hide(); } if (listener) { diff --git a/rtgui/saveformatpanel.h b/rtgui/saveformatpanel.h index c71759399..76ae7055d 100644 --- a/rtgui/saveformatpanel.h +++ b/rtgui/saveformatpanel.h @@ -37,7 +37,6 @@ class SaveFormatPanel : public Gtk::Grid, public AdjusterListener protected: Adjuster* jpegQual; - Adjuster* pngCompr; Gtk::CheckButton* tiffUncompressed; MyComboBoxText* format; MyComboBoxText* jpegSubSamp; diff --git a/rtgui/sharpening.cc b/rtgui/sharpening.cc index 72f4c62d8..9abfc6de8 100644 --- a/rtgui/sharpening.cc +++ b/rtgui/sharpening.cc @@ -423,13 +423,15 @@ void Sharpening::halocontrol_toggled () void Sharpening::method_changed () { - removeIfThere (this, usm, false); - removeIfThere (this, rld, false); + if (!batchMode) { + removeIfThere (this, usm, false); + removeIfThere (this, rld, false); - if (method->get_active_row_number() == 0) { - pack_start (*usm); - } else if (method->get_active_row_number() == 1) { - pack_start (*rld); + if (method->get_active_row_number() == 0) { + pack_start (*usm); + } else if (method->get_active_row_number() == 1) { + pack_start (*rld); + } } if (listener && (multiImage || getEnabled()) ) { @@ -447,6 +449,7 @@ void Sharpening::setBatchMode (bool batchMode) hcbin->pack_start (*hcbox); removeIfThere (edgebin, edgebox, false); edgebin->pack_start (*edgebox); + pack_start (*rld); radius->showEditedCB (); amount->showEditedCB (); @@ -461,16 +464,30 @@ void Sharpening::setBatchMode (bool batchMode) method->append (M("GENERAL_UNCHANGED")); } -void Sharpening::setAdjusterBehavior (bool amountadd) +void Sharpening::setAdjusterBehavior (bool radiusadd, bool amountadd, bool dampingadd, bool iteradd, bool edgetoladd, bool haloctrladd) { + radius->setAddMode(radiusadd); + dradius->setAddMode(radiusadd); amount->setAddMode(amountadd); damount->setAddMode(amountadd); + ddamping->setAddMode(dampingadd); + diter->setAddMode(iteradd); + eradius->setAddMode(radiusadd); + etolerance->setAddMode(edgetoladd); + hcamount->setAddMode(haloctrladd); } void Sharpening::trimValues (rtengine::procparams::ProcParams* pp) { + radius->trimValue(pp->sharpening.radius); + dradius->trimValue(pp->sharpening.deconvradius); amount->trimValue(pp->sharpening.amount); damount->trimValue(pp->sharpening.deconvamount); + ddamping->trimValue(pp->sharpening.deconvdamping); + diter->trimValue(pp->sharpening.deconviter); + eradius->trimValue(pp->sharpening.edges_radius); + etolerance->trimValue(pp->sharpening.edges_tolerance); + hcamount->trimValue(pp->sharpening.halocontrol_amount); } diff --git a/rtgui/sharpening.h b/rtgui/sharpening.h index 45c2d9fe1..2901036f5 100644 --- a/rtgui/sharpening.h +++ b/rtgui/sharpening.h @@ -70,7 +70,7 @@ public: void halocontrol_toggled (); void method_changed (); - void setAdjusterBehavior (bool amountadd); + void setAdjusterBehavior (bool radiusadd, bool amountadd, bool dampingadd, bool iteradd, bool edgetoladd, bool haloctrladd); void trimValues (rtengine::procparams::ProcParams* pp); }; diff --git a/rtgui/thumbbrowserentrybase.cc b/rtgui/thumbbrowserentrybase.cc index ff7e58d49..323900ae6 100644 --- a/rtgui/thumbbrowserentrybase.cc +++ b/rtgui/thumbbrowserentrybase.cc @@ -160,6 +160,7 @@ void ThumbBrowserEntryBase::updateBackBuffer () // draw icons onto the thumbnail area bbIcons = getIconsOnImageArea (); + bbSpecificityIcons = getSpecificityIconsOnImageArea (); int infow, infoh; getTextSizes (infow, infoh); @@ -224,6 +225,19 @@ void ThumbBrowserEntryBase::updateBackBuffer () } } + if (!bbSpecificityIcons.empty()) { + int igap = 2; + int istartx2 = prex + prew - 1 + igap; + int istarty2 = prey + preh - igap - 1; + + for (size_t i = 0; i < bbSpecificityIcons.size(); ++i) { + istartx2 -= bbSpecificityIcons[i]->get_width() - igap; + Gdk::Cairo::set_source_pixbuf(cc, bbSpecificityIcons[i], istartx2, istarty2 - bbSpecificityIcons[i]->get_height()); + cc->rectangle(istartx2, istarty2 - bbSpecificityIcons[i]->get_height(), bbSpecificityIcons[i]->get_width(), bbSpecificityIcons[i]->get_height()); + cc->fill(); + } + } + if ( ( (parent->getLocation() != ThumbBrowserBase::THLOC_EDITOR && options.showFileNames) || (parent->getLocation() == ThumbBrowserBase::THLOC_EDITOR && options.filmStripShowFileNames)) && withFilename > WFNAME_NONE) { @@ -448,7 +462,7 @@ void ThumbBrowserEntryBase::resize (int h) width = bsw + 2 * sideMargin + 2 * borderWidth; } - if ( preh != old_preh || width != old_width ) { + if (preh != old_preh) { delete [] preview; preview = nullptr; refreshThumbnailImage (); @@ -512,7 +526,9 @@ void ThumbBrowserEntryBase::draw (Cairo::RefPtr cc) } if (!backBuffer || selected != bbSelected || framed != bbFramed || preview != bbPreview - || exp_width != bbWidth || exp_height != bbHeight || getIconsOnImageArea () != bbIcons || backBuffer->isDirty()) { + || exp_width != bbWidth || exp_height != bbHeight || getIconsOnImageArea () != bbIcons + || getSpecificityIconsOnImageArea() != bbSpecificityIcons || backBuffer->isDirty()) + { updateBackBuffer (); } @@ -592,6 +608,11 @@ std::vector > ThumbBrowserEntryBase::getIconsOnImageAr return std::vector >(); } +std::vector > ThumbBrowserEntryBase::getSpecificityIconsOnImageArea() +{ + return std::vector >(); +} + void ThumbBrowserEntryBase::getIconSize(int& w, int& h) { w = 0; diff --git a/rtgui/thumbbrowserentrybase.h b/rtgui/thumbbrowserentrybase.h index f4779faa1..0ebf597e2 100644 --- a/rtgui/thumbbrowserentrybase.h +++ b/rtgui/thumbbrowserentrybase.h @@ -80,6 +80,7 @@ protected: bool bbSelected, bbFramed; guint8* bbPreview; std::vector > bbIcons; + std::vector > bbSpecificityIcons; CursorShape cursor_type; void drawFrame (Cairo::RefPtr cr, const Gdk::RGBA& bg, const Gdk::RGBA& fg); @@ -185,6 +186,7 @@ public: virtual void drawProgressBar (Glib::RefPtr win, const Gdk::RGBA& foregr, const Gdk::RGBA& backgr, int x, int w, int y, int h) {} virtual std::vector > getIconsOnImageArea (); + virtual std::vector > getSpecificityIconsOnImageArea (); virtual void getIconSize (int& w, int& h); virtual bool motionNotify (int x, int y); diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index 9db7c69b6..bfb1b8797 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -132,20 +132,22 @@ void Thumbnail::_generateThumbnailImage () bool quick = false; rtengine::RawMetaDataLocation ri; + rtengine::eSensorType sensorType = rtengine::ST_NONE; if ( initial_ && options.internalThumbIfUntouched) { quick = true; - tpp = rtengine::Thumbnail::loadQuickFromRaw (fname, ri, tw, th, 1, TRUE); + tpp = rtengine::Thumbnail::loadQuickFromRaw (fname, ri, sensorType, tw, th, 1, TRUE); } if ( tpp == nullptr ) { quick = false; - tpp = rtengine::Thumbnail::loadFromRaw (fname, ri, tw, th, 1, pparams.wb.equal, TRUE, pparams.raw.bayersensor.imageNum); + tpp = rtengine::Thumbnail::loadFromRaw (fname, ri, sensorType, tw, th, 1, pparams.wb.equal, TRUE); } + cfs.sensortype = sensorType; if (tpp) { cfs.format = FT_Raw; cfs.thumbImgType = quick ? CacheImageData::QUICK_THUMBNAIL : CacheImageData::FULL_THUMBNAIL; - infoFromImage (fname, &ri); + infoFromImage (fname, std::unique_ptr(new rtengine::RawMetaDataLocation(ri))); } } @@ -227,14 +229,16 @@ rtengine::procparams::ProcParams* Thumbnail::createProcParamsForUpdate(bool retu if (!run_cpb) { if (defProf == DEFPROFILE_DYNAMIC && create && cfs && cfs->exifValid) { - rtengine::ImageMetaData* imageMetaData; + rtengine::FramesMetaData* imageMetaData; if (getType() == FT_Raw) { - rtengine::RawMetaDataLocation metaData = rtengine::Thumbnail::loadMetaDataFromRaw(fname); - imageMetaData = rtengine::ImageMetaData::fromFile (fname, &metaData); + // Should we ask all frame's MetaData ? + imageMetaData = rtengine::FramesMetaData::fromFile (fname, std::unique_ptr(new rtengine::RawMetaDataLocation(rtengine::Thumbnail::loadMetaDataFromRaw(fname))), true); } else { - imageMetaData = rtengine::ImageMetaData::fromFile (fname, nullptr); + // Should we ask all frame's MetaData ? + imageMetaData = rtengine::FramesMetaData::fromFile (fname, nullptr, true); } PartialProfile *pp = ProfileStore::getInstance()->loadDynamicProfile(imageMetaData); + delete imageMetaData; int err = pp->pparams->save(outFName); pp->deleteInstance(); delete pp; @@ -249,25 +253,27 @@ rtengine::procparams::ProcParams* Thumbnail::createProcParamsForUpdate(bool retu } } else { // First generate the communication file, with general values and EXIF metadata - rtengine::ImageMetaData* imageMetaData; + rtengine::FramesMetaData* imageMetaData; if (getType() == FT_Raw) { - rtengine::RawMetaDataLocation metaData = rtengine::Thumbnail::loadMetaDataFromRaw(fname); - imageMetaData = rtengine::ImageMetaData::fromFile (fname, &metaData); + // Should we ask all frame's MetaData ? + imageMetaData = rtengine::FramesMetaData::fromFile (fname, std::unique_ptr(new rtengine::RawMetaDataLocation(rtengine::Thumbnail::loadMetaDataFromRaw(fname))), true); } else { - imageMetaData = rtengine::ImageMetaData::fromFile (fname, nullptr); + // Should we ask all frame's MetaData ? + imageMetaData = rtengine::FramesMetaData::fromFile (fname, nullptr, true); } Glib::ustring tmpFileName( Glib::build_filename(options.cacheBaseDir, Glib::ustring::compose("CPB_temp_%1.txt", index++)) ); const rtexif::TagDirectory* exifDir = nullptr; - if (imageMetaData && (exifDir = imageMetaData->getExifData())) { + if (imageMetaData && (exifDir = imageMetaData->getRootExifData())) { exifDir->CPBDump(tmpFileName, fname, outFName, defaultPparamsPath == DEFPROFILE_INTERNAL ? DEFPROFILE_INTERNAL : Glib::build_filename(defaultPparamsPath, Glib::path_get_basename(defProf) + paramFileExtension), cfs, flaggingMode); } + delete imageMetaData; // For the filename etc. do NOT use streams, since they are not UTF8 safe Glib::ustring cmdLine = options.CPBPath + Glib::ustring(" \"") + tmpFileName + Glib::ustring("\""); @@ -284,8 +290,6 @@ rtengine::procparams::ProcParams* Thumbnail::createProcParamsForUpdate(bool retu } g_remove (tmpFileName.c_str ()); - - delete imageMetaData; } if (returnParams && hasProcParams()) { @@ -497,6 +501,15 @@ bool Thumbnail::isEnqueued () return enqueueNumber > 0; } +bool Thumbnail::isPixelShift () +{ + return cfs.isPixelShift; +} +bool Thumbnail::isHDR () +{ + return cfs.isHDR; +} + void Thumbnail::increaseRef () { MyMutex::MyLock lock(mutex); @@ -599,10 +612,11 @@ rtengine::IImage8* Thumbnail::processThumbImage (const rtengine::procparams::Pro if ( cfs.thumbImgType == CacheImageData::QUICK_THUMBNAIL ) { // RAW internal thumbnail, no profile yet: just do some rotation etc. - image = tpp->quickProcessImage (pparams, h, rtengine::TI_Nearest, scale); + image = tpp->quickProcessImage (pparams, h, rtengine::TI_Nearest); } else { // Full thumbnail: apply profile - image = tpp->processImage (pparams, h, rtengine::TI_Bilinear, cfs.getCamera(), cfs.focalLen, cfs.focalLen35mm, cfs.focusDist, cfs.shutter, cfs.fnumber, cfs.iso, cfs.expcomp, scale ); + // image = tpp->processImage (pparams, h, rtengine::TI_Bilinear, cfs.getCamera(), cfs.focalLen, cfs.focalLen35mm, cfs.focusDist, cfs.shutter, cfs.fnumber, cfs.iso, cfs.expcomp, scale ); + image = tpp->processImage (pparams, static_cast(cfs.sensortype), h, rtengine::TI_Bilinear, &cfs, scale ); } tpp->getDimensions(lastW, lastH, lastScale); @@ -627,7 +641,8 @@ rtengine::IImage8* Thumbnail::upgradeThumbImage (const rtengine::procparams::Pro return nullptr; } - rtengine::IImage8* image = tpp->processImage (pparams, h, rtengine::TI_Bilinear, cfs.getCamera(), cfs.focalLen, cfs.focalLen35mm, cfs.focusDist, cfs.shutter, cfs.fnumber, cfs.iso, cfs.expcomp, scale ); + // rtengine::IImage8* image = tpp->processImage (pparams, h, rtengine::TI_Bilinear, cfs.getCamera(), cfs.focalLen, cfs.focalLen35mm, cfs.focusDist, cfs.shutter, cfs.fnumber, cfs.iso, cfs.expcomp, scale ); + rtengine::IImage8* image = tpp->processImage (pparams, static_cast(cfs.sensortype), h, rtengine::TI_Bilinear, &cfs, scale ); tpp->getDimensions(lastW, lastH, lastScale); delete tpp; @@ -645,7 +660,7 @@ void Thumbnail::generateExifDateTimeStrings () return; } - exifString = Glib::ustring::compose ("f/%1 %2s %3%4 %5mm", Glib::ustring(rtengine::ImageData::apertureToString(cfs.fnumber)), Glib::ustring(rtengine::ImageData::shutterToString(cfs.shutter)), M("QINFO_ISO"), cfs.iso, Glib::ustring::format(std::setw(3), std::fixed, std::setprecision(2), cfs.focalLen)); + exifString = Glib::ustring::compose ("f/%1 %2s %3%4 %5mm", Glib::ustring(rtengine::FramesData::apertureToString(cfs.fnumber)), Glib::ustring(rtengine::FramesData::shutterToString(cfs.shutter)), M("QINFO_ISO"), cfs.iso, Glib::ustring::format(std::setw(3), std::fixed, std::setprecision(2), cfs.focalLen)); if (options.fbShowExpComp && cfs.expcomp != "0.00" && cfs.expcomp != "") { // don't show exposure compensation if it is 0.00EV;old cache iles do not have ExpComp, so value will not be displayed. exifString = Glib::ustring::compose ("%1 %2EV", exifString, cfs.expcomp); // append exposure compensation to exifString @@ -709,10 +724,9 @@ ThFileType Thumbnail::getType () return (ThFileType) cfs.format; } -int Thumbnail::infoFromImage (const Glib::ustring& fname, rtengine::RawMetaDataLocation* rml) +int Thumbnail::infoFromImage (const Glib::ustring& fname, std::unique_ptr rml) { - - rtengine::ImageMetaData* idata = rtengine::ImageMetaData::fromFile (fname, rml); + rtengine::FramesMetaData* idata = rtengine::FramesMetaData::fromFile (fname, std::move(rml)); if (!idata) { return 0; @@ -723,24 +737,28 @@ int Thumbnail::infoFromImage (const Glib::ustring& fname, rtengine::RawMetaDataL cfs.exifValid = false; if (idata->hasExif()) { - cfs.shutter = idata->getShutterSpeed (); - cfs.fnumber = idata->getFNumber (); - cfs.focalLen = idata->getFocalLen (); + cfs.shutter = idata->getShutterSpeed (); + cfs.fnumber = idata->getFNumber (); + cfs.focalLen = idata->getFocalLen (); cfs.focalLen35mm = idata->getFocalLen35mm (); - cfs.focusDist = idata->getFocusDist (); - cfs.iso = idata->getISOSpeed (); - cfs.expcomp = idata->expcompToString (idata->getExpComp(), false); // do not mask Zero expcomp - cfs.year = 1900 + idata->getDateTime().tm_year; - cfs.month = idata->getDateTime().tm_mon + 1; - cfs.day = idata->getDateTime().tm_mday; - cfs.hour = idata->getDateTime().tm_hour; - cfs.min = idata->getDateTime().tm_min; - cfs.sec = idata->getDateTime().tm_sec; - cfs.timeValid = true; - cfs.exifValid = true; - cfs.lens = idata->getLens(); - cfs.camMake = idata->getMake(); - cfs.camModel = idata->getModel(); + cfs.focusDist = idata->getFocusDist (); + cfs.iso = idata->getISOSpeed (); + cfs.expcomp = idata->expcompToString (idata->getExpComp(), false); // do not mask Zero expcomp + cfs.isHDR = idata->getHDR (); + cfs.isPixelShift = idata->getPixelShift (); + cfs.frameCount = idata->getFrameCount (); + cfs.sampleFormat = idata->getSampleFormat (); + cfs.year = 1900 + idata->getDateTime().tm_year; + cfs.month = idata->getDateTime().tm_mon + 1; + cfs.day = idata->getDateTime().tm_mday; + cfs.hour = idata->getDateTime().tm_hour; + cfs.min = idata->getDateTime().tm_min; + cfs.sec = idata->getDateTime().tm_sec; + cfs.timeValid = true; + cfs.exifValid = true; + cfs.lens = idata->getLens(); + cfs.camMake = idata->getMake(); + cfs.camModel = idata->getModel(); if (idata->getOrientation() == "Rotate 90 CW") { deg = 90; @@ -865,7 +883,7 @@ void Thumbnail::_saveThumbnail () } // save thumbnail image - tpp->writeImage (getCacheFileName ("images", ""), 1); + tpp->writeImage (getCacheFileName ("images", "")); // save aehistogram tpp->writeAEHistogram (getCacheFileName ("aehistograms", "")); diff --git a/rtgui/thumbnail.h b/rtgui/thumbnail.h index eb9e38f7f..3ef094d6b 100644 --- a/rtgui/thumbnail.h +++ b/rtgui/thumbnail.h @@ -70,7 +70,7 @@ class Thumbnail void _loadThumbnail (bool firstTrial = true); void _saveThumbnail (); void _generateThumbnailImage (); - int infoFromImage (const Glib::ustring& fname, rtengine::RawMetaDataLocation* rml = nullptr); + int infoFromImage (const Glib::ustring& fname, std::unique_ptr rml = nullptr); void loadThumbnail (bool firstTrial = true); void generateExifDateTimeStrings (); @@ -107,6 +107,8 @@ public: void imageEnqueued (); void imageRemovedFromQueue (); bool isEnqueued (); + bool isPixelShift (); + bool isHDR (); // unsigned char* getThumbnailImage (int &w, int &h, int fixwh=1); // fixwh = 0: fix w and calculate h, =1: fix h and calculate w rtengine::IImage8* processThumbImage (const rtengine::procparams::ProcParams& pparams, int h, double& scale); diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index 64ed98537..908d43520 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -28,7 +28,7 @@ using namespace rtengine::procparams; -ToolPanelCoordinator::ToolPanelCoordinator () : ipc(nullptr), hasChanged(false), editDataProvider(nullptr) +ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), hasChanged (false), editDataProvider (nullptr) { exposurePanel = Gtk::manage (new ToolVBox ()); @@ -54,14 +54,13 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(nullptr), hasChanged(false), colortoning = Gtk::manage (new ColorToning ()); lensgeom = Gtk::manage (new LensGeometry ()); lensProf = Gtk::manage (new LensProfilePanel ()); - lensProf->setLensGeomRef(lensgeom); distortion = Gtk::manage (new Distortion ()); rotate = Gtk::manage (new Rotate ()); vibrance = Gtk::manage (new Vibrance ()); colorappearance = Gtk::manage (new ColorAppearance ()); whitebalance = Gtk::manage (new WhiteBalance ()); vignetting = Gtk::manage (new Vignetting ()); - retinex = Gtk::manage (new Retinex ()); + retinex = Gtk::manage (new Retinex ()); gradient = Gtk::manage (new Gradient ()); pcvignette = Gtk::manage (new PCVignette ()); perspective = Gtk::manage (new PerspCorrection ()); @@ -72,8 +71,10 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(nullptr), hasChanged(false), prsharpening = Gtk::manage (new PrSharpening()); crop = Gtk::manage (new Crop ()); icm = Gtk::manage (new ICMPanel ()); - exifpanel = Gtk::manage (new ExifPanel ()); - iptcpanel = Gtk::manage (new IPTCPanel ()); + if(!batch) { + exifpanel = Gtk::manage (new ExifPanel ()); + iptcpanel = Gtk::manage (new IPTCPanel ()); + } wavelet = Gtk::manage (new Wavelet ()); dirpyrequalizer = Gtk::manage (new DirPyrEqualizer ()); hsvequalizer = Gtk::manage (new HSVEqualizer ()); @@ -90,6 +91,7 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(nullptr), hasChanged(false), rawexposure = Gtk::manage (new RAWExposure ()); bayerrawexposure = Gtk::manage (new BayerRAWExposure ()); xtransrawexposure = Gtk::manage (new XTransRAWExposure ()); + fattal = Gtk::manage (new FattalToneMapping ()); // So Demosaic, Line noise filter, Green Equilibration, Ca-Correction (garder le nom de section identique!) and Black-Level will be moved in a "Bayer sensor" tool, // and a separate Demosaic and Black Level tool will be created in an "X-Trans sensor" tool @@ -101,113 +103,70 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(nullptr), hasChanged(false), // Medium -> High ISO addPanel (colorPanel, whitebalance); - toolPanels.push_back (whitebalance); addPanel (exposurePanel, toneCurve); - toolPanels.push_back (toneCurve); addPanel (colorPanel, vibrance); - toolPanels.push_back (vibrance); addPanel (colorPanel, chmixer); - toolPanels.push_back (chmixer); // << TODO: Add "Enabled" addPanel (colorPanel, blackwhite); - toolPanels.push_back (blackwhite); addPanel (exposurePanel, shadowshighlights); - toolPanels.push_back (shadowshighlights); addPanel (detailsPanel, spot); - toolPanels.push_back (spot); addPanel (detailsPanel, sharpening); - toolPanels.push_back (sharpening); addPanel (detailsPanel, sharpenEdge); - toolPanels.push_back (sharpenEdge); addPanel (detailsPanel, sharpenMicro); - toolPanels.push_back (sharpenMicro); addPanel (colorPanel, hsvequalizer); - toolPanels.push_back (hsvequalizer); // << TODO: Add "Enabled" addPanel (colorPanel, filmSimulation); - toolPanels.push_back (filmSimulation); addPanel (colorPanel, rgbcurves); - toolPanels.push_back (rgbcurves); // << TODO: Add "Enabled" addPanel (colorPanel, colortoning); - toolPanels.push_back (colortoning); addPanel (exposurePanel, epd); - toolPanels.push_back (epd); + addPanel (exposurePanel, fattal); addPanel (exposurePanel, retinex); - toolPanels.push_back (retinex); addPanel (exposurePanel, pcvignette); - toolPanels.push_back (pcvignette); addPanel (exposurePanel, gradient); - toolPanels.push_back (gradient); addPanel (exposurePanel, lcurve); - toolPanels.push_back (lcurve); // << TODO: Add "Enabled" ??? addPanel (exposurePanel, colorappearance); - toolPanels.push_back (colorappearance); addPanel (detailsPanel, impulsedenoise); - toolPanels.push_back (impulsedenoise); addPanel (detailsPanel, dirpyrdenoise); - toolPanels.push_back (dirpyrdenoise); addPanel (detailsPanel, defringe); - toolPanels.push_back (defringe); addPanel (detailsPanel, dirpyrequalizer); - toolPanels.push_back (dirpyrequalizer); addPanel (waveletPanel, wavelet); - toolPanels.push_back (wavelet); addPanel (transformPanel, crop); - toolPanels.push_back (crop); addPanel (transformPanel, resize); - toolPanels.push_back (resize); addPanel (resize->getPackBox(), prsharpening, 2); - toolPanels.push_back (prsharpening); addPanel (transformPanel, lensgeom); - toolPanels.push_back (lensgeom); addPanel (lensgeom->getPackBox(), rotate, 2); - toolPanels.push_back (rotate); addPanel (lensgeom->getPackBox(), perspective, 2); - toolPanels.push_back (perspective); addPanel (lensgeom->getPackBox(), lensProf, 2); - toolPanels.push_back (lensProf); addPanel (lensgeom->getPackBox(), distortion, 2); - toolPanels.push_back (distortion); addPanel (lensgeom->getPackBox(), cacorrection, 2); - toolPanels.push_back (cacorrection); addPanel (lensgeom->getPackBox(), vignetting, 2); - toolPanels.push_back (vignetting); addPanel (colorPanel, icm); - toolPanels.push_back (icm); addPanel (rawPanel, sensorbayer); - toolPanels.push_back (sensorbayer); addPanel (sensorbayer->getPackBox(), bayerprocess, 2); - toolPanels.push_back (bayerprocess); addPanel (sensorbayer->getPackBox(), bayerrawexposure, 2); - toolPanels.push_back (bayerrawexposure); addPanel (sensorbayer->getPackBox(), bayerpreprocess, 2); - toolPanels.push_back (bayerpreprocess); addPanel (sensorbayer->getPackBox(), rawcacorrection, 2); - toolPanels.push_back (rawcacorrection); addPanel (rawPanel, sensorxtrans); - toolPanels.push_back (sensorxtrans); addPanel (sensorxtrans->getPackBox(), xtransprocess, 2); - toolPanels.push_back (xtransprocess); addPanel (sensorxtrans->getPackBox(), xtransrawexposure, 2); - toolPanels.push_back (xtransrawexposure); addPanel (rawPanel, rawexposure); - toolPanels.push_back (rawexposure); addPanel (rawPanel, preprocess); - toolPanels.push_back (preprocess); addPanel (rawPanel, darkframe); - toolPanels.push_back (darkframe); addPanel (rawPanel, flatfield); - toolPanels.push_back (flatfield); toolPanels.push_back (coarse); - toolPanels.push_back (exifpanel); - toolPanels.push_back (iptcpanel); - metadataPanel = Gtk::manage (new Gtk::Notebook ()); - metadataPanel->set_name ("MetaPanelNotebook"); + if(!batch) { + toolPanels.push_back (exifpanel); + toolPanels.push_back (iptcpanel); + metadataPanel = Gtk::manage (new Gtk::Notebook ()); + metadataPanel->set_name ("MetaPanelNotebook"); + metadataPanel->append_page (*exifpanel, M ("MAIN_TAB_EXIF")); + metadataPanel->append_page (*iptcpanel, M ("MAIN_TAB_IPTC")); + } else { + metadataPanel = nullptr; + } toolPanelNotebook = new Gtk::Notebook (); toolPanelNotebook->set_name ("ToolPanelNotebook"); - metadataPanel->append_page (*exifpanel, M("MAIN_TAB_EXIF")); - metadataPanel->append_page (*iptcpanel, M("MAIN_TAB_IPTC")); exposurePanelSW = Gtk::manage (new MyScrolledWindow ()); detailsPanelSW = Gtk::manage (new MyScrolledWindow ()); @@ -220,47 +179,51 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(nullptr), hasChanged(false), // load panel endings for (int i = 0; i < 6; i++) { vbPanelEnd[i] = Gtk::manage (new Gtk::VBox ()); - imgPanelEnd[i] = Gtk::manage (new RTImage("PanelEnding.png")); + imgPanelEnd[i] = Gtk::manage (new RTImage ("PanelEnding.png")); imgPanelEnd[i]->show (); vbPanelEnd[i]->pack_start (*imgPanelEnd[i], Gtk::PACK_SHRINK); vbPanelEnd[i]->show_all(); } exposurePanelSW->add (*exposurePanel); - exposurePanel->pack_start (*Gtk::manage(new Gtk::HSeparator), Gtk::PACK_SHRINK, 0); + exposurePanel->pack_start (*Gtk::manage (new Gtk::HSeparator), Gtk::PACK_SHRINK, 0); exposurePanel->pack_start (*vbPanelEnd[0], Gtk::PACK_SHRINK, 4); detailsPanelSW->add (*detailsPanel); - detailsPanel->pack_start (*Gtk::manage(new Gtk::HSeparator), Gtk::PACK_SHRINK, 0); + detailsPanel->pack_start (*Gtk::manage (new Gtk::HSeparator), Gtk::PACK_SHRINK, 0); detailsPanel->pack_start (*vbPanelEnd[1], Gtk::PACK_SHRINK, 4); colorPanelSW->add (*colorPanel); - colorPanel->pack_start (*Gtk::manage(new Gtk::HSeparator), Gtk::PACK_SHRINK, 0); + colorPanel->pack_start (*Gtk::manage (new Gtk::HSeparator), Gtk::PACK_SHRINK, 0); colorPanel->pack_start (*vbPanelEnd[2], Gtk::PACK_SHRINK, 4); waveletPanelSW->add (*waveletPanel); - waveletPanel->pack_start (*Gtk::manage(new Gtk::HSeparator), Gtk::PACK_SHRINK, 0); + waveletPanel->pack_start (*Gtk::manage (new Gtk::HSeparator), Gtk::PACK_SHRINK, 0); waveletPanel->pack_start (*vbPanelEnd[5], Gtk::PACK_SHRINK, 0); transformPanelSW->add (*transformPanel); - transformPanel->pack_start (*Gtk::manage(new Gtk::HSeparator), Gtk::PACK_SHRINK, 0); + transformPanel->pack_start (*Gtk::manage (new Gtk::HSeparator), Gtk::PACK_SHRINK, 0); transformPanel->pack_start (*vbPanelEnd[3], Gtk::PACK_SHRINK, 4); rawPanelSW->add (*rawPanel); - rawPanel->pack_start (*Gtk::manage(new Gtk::HSeparator), Gtk::PACK_SHRINK, 0); + rawPanel->pack_start (*Gtk::manage (new Gtk::HSeparator), Gtk::PACK_SHRINK, 0); rawPanel->pack_start (*vbPanelEnd[4], Gtk::PACK_SHRINK, 0); TOITypes type = options.UseIconNoText ? TOI_ICON : TOI_TEXT; - toiE = Gtk::manage (new TextOrIcon ("exposure.png" , M("MAIN_TAB_EXPOSURE") , M("MAIN_TAB_EXPOSURE_TOOLTIP") , type)); - toiD = Gtk::manage (new TextOrIcon ("detail.png" , M("MAIN_TAB_DETAIL") , M("MAIN_TAB_DETAIL_TOOLTIP") , type)); - toiC = Gtk::manage (new TextOrIcon ("colour.png" , M("MAIN_TAB_COLOR") , M("MAIN_TAB_COLOR_TOOLTIP") , type)); - toiW = Gtk::manage (new TextOrIcon ("wavelet.png" , M("MAIN_TAB_WAVELET") , M("MAIN_TAB_WAVELET_TOOLTIP") , type)); - toiT = Gtk::manage (new TextOrIcon ("transform.png", M("MAIN_TAB_TRANSFORM"), M("MAIN_TAB_TRANSFORM_TOOLTIP"), type)); - toiR = Gtk::manage (new TextOrIcon ("raw.png" , M("MAIN_TAB_RAW") , M("MAIN_TAB_RAW_TOOLTIP") , type)); - toiM = Gtk::manage (new TextOrIcon ("meta.png" , M("MAIN_TAB_METADATA") , M("MAIN_TAB_METADATA_TOOLTIP") , type)); + toiE = Gtk::manage (new TextOrIcon ("exposure.png", M ("MAIN_TAB_EXPOSURE"), M ("MAIN_TAB_EXPOSURE_TOOLTIP"), type)); + toiD = Gtk::manage (new TextOrIcon ("detail.png", M ("MAIN_TAB_DETAIL"), M ("MAIN_TAB_DETAIL_TOOLTIP"), type)); + toiC = Gtk::manage (new TextOrIcon ("colour.png", M ("MAIN_TAB_COLOR"), M ("MAIN_TAB_COLOR_TOOLTIP"), type)); + toiW = Gtk::manage (new TextOrIcon ("wavelet.png", M ("MAIN_TAB_WAVELET"), M ("MAIN_TAB_WAVELET_TOOLTIP"), type)); + toiT = Gtk::manage (new TextOrIcon ("transform.png", M ("MAIN_TAB_TRANSFORM"), M ("MAIN_TAB_TRANSFORM_TOOLTIP"), type)); + toiR = Gtk::manage (new TextOrIcon ("raw.png", M ("MAIN_TAB_RAW"), M ("MAIN_TAB_RAW_TOOLTIP"), type)); + if(!batch) { + toiM = Gtk::manage (new TextOrIcon ("meta.png", M ("MAIN_TAB_METADATA"), M ("MAIN_TAB_METADATA_TOOLTIP"), type)); + } else { + toiM = nullptr; + } toolPanelNotebook->append_page (*exposurePanelSW, *toiE); toolPanelNotebook->append_page (*detailsPanelSW, *toiD); @@ -268,7 +231,9 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(nullptr), hasChanged(false), toolPanelNotebook->append_page (*waveletPanelSW, *toiW); toolPanelNotebook->append_page (*transformPanelSW, *toiT); toolPanelNotebook->append_page (*rawPanelSW, *toiR); - toolPanelNotebook->append_page (*metadataPanel, *toiM); + if(!batch) { + toolPanelNotebook->append_page (*metadataPanel, *toiM); + } toolPanelNotebook->set_current_page (0); @@ -290,17 +255,18 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(nullptr), hasChanged(false), icm->setICMPanelListener (this); toolBar = new ToolBar (); - toolBar->setToolBarListener(this); + toolBar->setToolBarListener (this); } void ToolPanelCoordinator::addPanel (Gtk::Box* where, FoldableToolPanel* panel, int level) { - panel->setParent(where); - panel->setLevel(level); + panel->setParent (where); + panel->setLevel (level); expList.push_back (panel->getExpander()); - where->pack_start(*panel->getExpander(), false, false); + where->pack_start (*panel->getExpander(), false, false); + toolPanels.push_back (panel); } ToolPanelCoordinator::~ToolPanelCoordinator () @@ -312,12 +278,13 @@ ToolPanelCoordinator::~ToolPanelCoordinator () delete toolBar; } -void ToolPanelCoordinator::imageTypeChanged(bool isRaw, bool isBayer, bool isXtrans) +void ToolPanelCoordinator::imageTypeChanged (bool isRaw, bool isBayer, bool isXtrans) { GThreadLock lock; - if(isRaw) { - rawPanelSW->set_sensitive(true); + if (isRaw) { + rawPanelSW->set_sensitive (true); + if (isBayer) { sensorxtrans->FoldableToolPanel::hide(); sensorbayer->FoldableToolPanel::show(); @@ -335,7 +302,7 @@ void ToolPanelCoordinator::imageTypeChanged(bool isRaw, bool isBayer, bool isXtr flatfield->FoldableToolPanel::hide(); } } else { - rawPanelSW->set_sensitive(false); + rawPanelSW->set_sensitive (false); } } @@ -348,7 +315,7 @@ void ToolPanelCoordinator::panelChanged (rtengine::ProcEvent event, const Glib:: return; } - int changeFlags = refreshmap[(int)event]; + int changeFlags = refreshmap[ (int)event]; ProcParams* params = ipc->beginUpdateParams (); @@ -358,14 +325,15 @@ void ToolPanelCoordinator::panelChanged (rtengine::ProcEvent event, const Glib:: // Compensate rotation on flip if (event == rtengine::EvCTHFlip || event == rtengine::EvCTVFlip) { - if (fabs(params->rotate.degree) > 0.001) { + if (fabs (params->rotate.degree) > 0.001) { params->rotate.degree *= -1; - changeFlags |= refreshmap[(int)rtengine::EvROTDegree]; + changeFlags |= refreshmap[ (int)rtengine::EvROTDegree]; rotate->read (params); } } int tr = TR_NONE; + if (params->coarse.rotate == 90) { tr = TR_R90; } else if (params->coarse.rotate == 180) { @@ -430,14 +398,14 @@ void ToolPanelCoordinator::profileChange (const PartialProfile *nparams, rtengi } // And apply the partial profile nparams to mergedParams - nparams->applyTo(mergedParams); + nparams->applyTo (mergedParams); // Derive the effective changes, if it's a profile change, to prevent slow RAW rerendering if not necessary bool filterRawRefresh = false; if (event != rtengine::EvPhotoLoaded) { - ParamsEdited pe(true); - std::vector lParams(2); + ParamsEdited pe (true); + std::vector lParams (2); lParams[0] = *params; lParams[1] = *mergedParams; pe.initFrom (lParams); @@ -449,6 +417,7 @@ void ToolPanelCoordinator::profileChange (const PartialProfile *nparams, rtengi delete mergedParams; tr = TR_NONE; + if (params->coarse.rotate == 90) { tr = TR_R90; } else if (params->coarse.rotate == 180) { @@ -459,7 +428,7 @@ void ToolPanelCoordinator::profileChange (const PartialProfile *nparams, rtengi // trimming overflowing cropped area ipc->getInitialImage()->getImageSource()->getFullSize (fw, fh, tr); - crop->trim(params, fw, fh); + crop->trim (params, fw, fh); // updating the GUI with updated values for (auto toolPanel : toolPanels) { @@ -477,7 +446,7 @@ void ToolPanelCoordinator::profileChange (const PartialProfile *nparams, rtengi // start the IPC processing if (filterRawRefresh) { - ipc->endUpdateParams ( refreshmap[(int)event] & ALLNORAW ); + ipc->endUpdateParams ( refreshmap[ (int)event] & ALLNORAW ); } else { ipc->endUpdateParams (event); } @@ -513,7 +482,7 @@ void ToolPanelCoordinator::initImage (rtengine::StagedImageProcessor* ipc_, bool toneCurve->enableListener (); if (ipc) { - const rtengine::ImageMetaData* pMetaData = ipc->getInitialImage()->getMetaData(); + const rtengine::FramesMetaData* pMetaData = ipc->getInitialImage()->getMetaData(); exifpanel->setImageData (pMetaData); iptcpanel->setImageData (pMetaData); @@ -529,9 +498,9 @@ void ToolPanelCoordinator::initImage (rtengine::StagedImageProcessor* ipc_, bool ipc->setSizeListener (crop); ipc->setSizeListener (resize); ipc->setImageTypeListener (this); - flatfield->setShortcutPath(Glib::path_get_dirname(ipc->getInitialImage()->getFileName())); + flatfield->setShortcutPath (Glib::path_get_dirname (ipc->getInitialImage()->getFileName())); - icm->setRawMeta (raw, (const rtengine::ImageData*)pMetaData); + icm->setRawMeta (raw, (const rtengine::FramesData*)pMetaData); lensProf->setRawMeta (raw, pMetaData); } @@ -555,7 +524,7 @@ void ToolPanelCoordinator::closeAllTools() for (size_t i = 0; i < options.tpOpen.size(); i++) if (i < expList.size()) { - expList.at(i)->set_expanded (false); + expList.at (i)->set_expanded (false); } } @@ -564,7 +533,7 @@ void ToolPanelCoordinator::openAllTools() for (size_t i = 0; i < options.tpOpen.size(); i++) if (i < expList.size()) { - expList.at(i)->set_expanded (true); + expList.at (i)->set_expanded (true); } } @@ -573,20 +542,20 @@ 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)); + expList.at (i)->set_expanded (options.tpOpen.at (i)); } - if(options.tpOpen.size() > expList.size()) { + if (options.tpOpen.size() > expList.size()) { 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())); + temp.push_back (options.tpOpen.at (i + expList.size())); } - wavelet->updateToolState(temp); - wavelet->setExpanded(true); - retinex->updateToolState(temp); + wavelet->updateToolState (temp); + wavelet->setExpanded (true); + retinex->updateToolState (temp); } } @@ -600,14 +569,23 @@ void ToolPanelCoordinator::writeOptions () { crop->writeOptions (); - options.tpOpen.clear (); + + if (options.autoSaveTpOpen) { + writeToolExpandedStatus (options.tpOpen); + } +} + + +void ToolPanelCoordinator::writeToolExpandedStatus (std::vector &tpOpen) +{ + tpOpen.clear (); for (size_t i = 0; i < expList.size(); i++) { - options.tpOpen.push_back (expList.at(i)->get_expanded ()); + tpOpen.push_back (expList.at (i)->get_expanded ()); } - wavelet->writeOptions(options.tpOpen); - retinex->writeOptions(options.tpOpen); + wavelet->writeOptions (tpOpen); + retinex->writeOptions (tpOpen); } @@ -680,16 +658,16 @@ rtengine::RawImage* ToolPanelCoordinator::getDF() return nullptr; } - const rtengine::ImageMetaData *imd = ipc->getInitialImage()->getMetaData(); + const rtengine::FramesMetaData *imd = ipc->getInitialImage()->getMetaData(); - if(imd) { + if (imd) { int iso = imd->getISOSpeed(); double shutter = imd->getShutterSpeed(); - std::string maker( imd->getMake() ); - std::string model( imd->getModel() ); + std::string maker ( imd->getMake() ); + std::string model ( imd->getModel() ); time_t timestamp = imd->getDateTimeAsTS(); - return rtengine::dfm.searchDarkFrame( maker, model, iso, shutter, timestamp); + return rtengine::dfm.searchDarkFrame ( maker, model, iso, shutter, timestamp); } return nullptr; @@ -701,19 +679,19 @@ rtengine::RawImage* ToolPanelCoordinator::getFF() return nullptr; } - const rtengine::ImageMetaData *imd = ipc->getInitialImage()->getMetaData(); + const rtengine::FramesMetaData *imd = ipc->getInitialImage()->getMetaData(); - if(imd) { + if (imd) { // int iso = imd->getISOSpeed(); temporarilly removed because unused // double shutter = imd->getShutterSpeed(); temporarilly removed because unused double aperture = imd->getFNumber(); double focallength = imd->getFocalLen(); - std::string maker( imd->getMake() ); - std::string model( imd->getModel() ); - std::string lens( imd->getLens() ); + std::string maker ( imd->getMake() ); + std::string model ( imd->getModel() ); + std::string lens ( imd->getLens() ); time_t timestamp = imd->getDateTimeAsTS(); - return rtengine::ffm.searchFlatField( maker, model, lens, focallength, aperture, timestamp); + return rtengine::ffm.searchFlatField ( maker, model, lens, focallength, aperture, timestamp); } return nullptr; @@ -786,8 +764,8 @@ void ToolPanelCoordinator::updateCurveBackgroundHistogram (LUTu & histToneCurve, colorappearance->updateCurveBackgroundHistogram (histToneCurve, histLCurve, histCCurve, /*histCLurve, histLLCurve,*/ histLCAM, histCCAM, histRed, histGreen, histBlue, histLuma, histLRETI); toneCurve->updateCurveBackgroundHistogram (histToneCurve, histLCurve, histCCurve,/* histCLurve, histLLCurve,*/ histLCAM, histCCAM, histRed, histGreen, histBlue, histLuma, histLRETI); lcurve->updateCurveBackgroundHistogram (histToneCurve, histLCurve, histCCurve, /*histCLurve, histLLCurve,*/ histLCAM, histCCAM, histRed, histGreen, histBlue, histLuma, histLRETI); - rgbcurves->updateCurveBackgroundHistogram(histToneCurve, histLCurve, histCCurve,/* histCLurve, histLLCurve, */histLCAM, histCCAM, histRed, histGreen, histBlue, histLuma, histLRETI); - retinex->updateCurveBackgroundHistogram(histToneCurve, histLCurve, histCCurve,/* histCLurve, histLLCurve, */histLCAM, histCCAM, histRed, histGreen, histBlue, histLuma, histLRETI); + rgbcurves->updateCurveBackgroundHistogram (histToneCurve, histLCurve, histCCurve,/* histCLurve, histLLCurve, */histLCAM, histCCAM, histRed, histGreen, histBlue, histLuma, histLRETI); + retinex->updateCurveBackgroundHistogram (histToneCurve, histLCurve, histCCurve,/* histCLurve, histLLCurve, */histLCAM, histCCAM, histRed, histGreen, histBlue, histLuma, histLRETI); } @@ -801,10 +779,10 @@ void ToolPanelCoordinator::foldAllButOne (Gtk::Box* parent, FoldableToolPanel* o if (currentTP->getParent() == parent) { // Section in the same tab, we unfold it if it's not the one that has been clicked if (currentTP != openedSection) { - currentTP->setExpanded(false); + currentTP->setExpanded (false); } else { if (!currentTP->getExpanded()) { - currentTP->setExpanded(true); + currentTP->setExpanded (true); } } } @@ -820,36 +798,36 @@ bool ToolPanelCoordinator::handleShortcutKey (GdkEventKey* event) bool alt = event->state & GDK_MOD1_MASK; if (alt) { - switch(event->keyval) { - case GDK_KEY_e: - toolPanelNotebook->set_current_page (toolPanelNotebook->page_num(*exposurePanelSW)); - return true; - - case GDK_KEY_d: - toolPanelNotebook->set_current_page (toolPanelNotebook->page_num(*detailsPanelSW)); - return true; - - case GDK_KEY_c: - toolPanelNotebook->set_current_page (toolPanelNotebook->page_num(*colorPanelSW)); - return true; - - case GDK_KEY_t: - toolPanelNotebook->set_current_page (toolPanelNotebook->page_num(*transformPanelSW)); - return true; - - case GDK_KEY_r: - toolPanelNotebook->set_current_page (toolPanelNotebook->page_num(*rawPanelSW)); - return true; - - case GDK_KEY_w: - toolPanelNotebook->set_current_page (toolPanelNotebook->page_num(*waveletPanelSW)); - return true; - - case GDK_KEY_m: - if (metadataPanel) { - toolPanelNotebook->set_current_page (toolPanelNotebook->page_num(*metadataPanel)); + switch (event->keyval) { + case GDK_KEY_e: + toolPanelNotebook->set_current_page (toolPanelNotebook->page_num (*exposurePanelSW)); return true; - } + + case GDK_KEY_d: + toolPanelNotebook->set_current_page (toolPanelNotebook->page_num (*detailsPanelSW)); + return true; + + case GDK_KEY_c: + toolPanelNotebook->set_current_page (toolPanelNotebook->page_num (*colorPanelSW)); + return true; + + case GDK_KEY_t: + toolPanelNotebook->set_current_page (toolPanelNotebook->page_num (*transformPanelSW)); + return true; + + case GDK_KEY_r: + toolPanelNotebook->set_current_page (toolPanelNotebook->page_num (*rawPanelSW)); + return true; + + case GDK_KEY_w: + toolPanelNotebook->set_current_page (toolPanelNotebook->page_num (*waveletPanelSW)); + return true; + + case GDK_KEY_m: + if (metadataPanel) { + toolPanelNotebook->set_current_page (toolPanelNotebook->page_num (*metadataPanel)); + return true; + } } } @@ -868,7 +846,7 @@ void ToolPanelCoordinator::updateVScrollbars (bool hide) waveletPanelSW->set_policy (Gtk::POLICY_AUTOMATIC, policy); for (auto currExp : expList) { - currExp->updateVScrollbars(hide); + currExp->updateVScrollbars (hide); } } @@ -877,14 +855,14 @@ void ToolPanelCoordinator::updateTabsHeader (bool useIcons) GThreadLock lock; // All GUI acces from idle_add callbacks or separate thread HAVE to be protected TOITypes type = useIcons ? TOI_ICON : TOI_TEXT; - toiE->switchTo(type); - toiD->switchTo(type); - toiC->switchTo(type); - toiT->switchTo(type); - toiR->switchTo(type); + toiE->switchTo (type); + toiD->switchTo (type); + toiC->switchTo (type); + toiT->switchTo (type); + toiR->switchTo (type); if (toiM) { - toiM->switchTo(type); + toiM->switchTo (type); } } @@ -903,24 +881,24 @@ void ToolPanelCoordinator::toolSelected (ToolMode tool) GThreadLock lock; // All GUI acces from idle_add callbacks or separate thread HAVE to be protected switch (tool) { - case TMCropSelect: - crop->setExpanded(true); - toolPanelNotebook->set_current_page(toolPanelNotebook->page_num(*transformPanelSW)); - break; + case TMCropSelect: + crop->setExpanded (true); + toolPanelNotebook->set_current_page (toolPanelNotebook->page_num (*transformPanelSW)); + break; - case TMSpotWB: - whitebalance->setExpanded(true); - toolPanelNotebook->set_current_page(toolPanelNotebook->page_num(*colorPanelSW)); - break; + case TMSpotWB: + whitebalance->setExpanded (true); + toolPanelNotebook->set_current_page (toolPanelNotebook->page_num (*colorPanelSW)); + break; - case TMStraighten: - lensgeom->setExpanded(true); - rotate->setExpanded(true); - toolPanelNotebook->set_current_page(toolPanelNotebook->page_num(*transformPanelSW)); - break; + case TMStraighten: + lensgeom->setExpanded (true); + rotate->setExpanded (true); + toolPanelNotebook->set_current_page (toolPanelNotebook->page_num (*transformPanelSW)); + break; - default: - break; + default: + break; } } @@ -934,14 +912,14 @@ void ToolPanelCoordinator::editModeSwitchedOff () void ToolPanelCoordinator::dirSelected (const Glib::ustring& dirname, const Glib::ustring& openfile) { - flatfield->setShortcutPath(dirname); + flatfield->setShortcutPath (dirname); } -void ToolPanelCoordinator::setEditProvider(EditDataProvider *provider) +void ToolPanelCoordinator::setEditProvider (EditDataProvider *provider) { editDataProvider = provider; for (size_t i = 0; i < toolPanels.size(); i++) { - toolPanels.at(i)->setEditProvider(provider); + toolPanels.at (i)->setEditProvider (provider); } } diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h index c93e9efe3..cc31c4e6c 100644 --- a/rtgui/toolpanelcoord.h +++ b/rtgui/toolpanelcoord.h @@ -79,6 +79,7 @@ #include "colortoning.h" #include "filmsimulation.h" #include "prsharpening.h" +#include "fattaltonemap.h" #include "guiutils.h" class ImageEditorCoordinator; @@ -147,6 +148,7 @@ protected: RAWExposure* rawexposure; BayerRAWExposure* bayerrawexposure; XTransRAWExposure* xtransrawexposure; + FattalToneMapping *fattal; std::vector paramcListeners; @@ -200,7 +202,7 @@ public: CoarsePanel* coarse; Gtk::Notebook* toolPanelNotebook; - ToolPanelCoordinator (); + ToolPanelCoordinator (bool batch = false); virtual ~ToolPanelCoordinator (); bool getChangedState () @@ -219,7 +221,7 @@ public: // toolpanellistener interface void panelChanged (rtengine::ProcEvent event, const Glib::ustring& descr); - void imageTypeChanged(bool isRaw, bool isBayer, bool isXtrans); + void imageTypeChanged (bool isRaw, bool isBayer, bool isXtrans); // profilechangelistener interface void profileChange (const rtengine::procparams::PartialProfile* nparams, rtengine::ProcEvent event, const Glib::ustring& descr, const ParamsEdited* paramsEdited = nullptr); void setDefaults (rtengine::procparams::ProcParams* defparams); @@ -241,6 +243,8 @@ public: // read/write the "expanded" state of the expanders & read/write the crop panel settings (ratio, guide type, etc.) void readOptions (); void writeOptions (); + void writeToolExpandedStatus (std::vector &tpOpen); + // wbprovider interface void getAutoWB (double& temp, double& green, double equal, double tempBias) @@ -299,7 +303,7 @@ public: void toolSelected (ToolMode tool); void editModeSwitchedOff (); - void setEditProvider(EditDataProvider *provider); + void setEditProvider (EditDataProvider *provider); }; #endif diff --git a/rtgui/xtransprocess.cc b/rtgui/xtransprocess.cc index a663ac7c5..453f0a53d 100644 --- a/rtgui/xtransprocess.cc +++ b/rtgui/xtransprocess.cc @@ -19,7 +19,7 @@ #include "xtransprocess.h" #include "options.h" #include "guiutils.h" -#include + using namespace rtengine; using namespace rtengine::procparams; @@ -30,8 +30,30 @@ XTransProcess::XTransProcess () : FoldableToolPanel(this, "xtransprocess", M("TP method = Gtk::manage (new MyComboBoxText ()); for( size_t i = 0; i < procparams::RAWParams::XTransSensor::numMethods; i++) { - static const std::regex what ("[() -]"); - const std::string langKey = std::regex_replace (procparams::RAWParams::XTransSensor::methodstring[i], what, ""); + const std::string langKey = + [i]() -> std::string + { + const std::string str(procparams::RAWParams::XTransSensor::methodstring[i]); + + std::string res; + for (const auto& c : str) { + switch (c) { + case '(': + case ')': + case ' ': + case '-': { + continue; + } + + default: { + res += c; + break; + } + } + } + + return res; + }(); method->append(M("TP_RAW_" + Glib::ustring(langKey).uppercase())); } diff --git a/tools/generateLensList b/tools/generateRtexifUpdates similarity index 67% rename from tools/generateLensList rename to tools/generateRtexifUpdates index 13738a359..cdc0dd70c 100755 --- a/tools/generateLensList +++ b/tools/generateRtexifUpdates @@ -1,12 +1,12 @@ #!/usr/bin/env bash # This Bash4 script generates lens ID and other parameter lists for rtexif/*.cc -# files using ExifTool. It uses xmlstarlet to parse ExifTool's output. +# using ExifTool. It uses xmlstarlet to parse ExifTool's output. # # Run the script from the project root: -# ./tools/generateLensList +# ./tools/generateRtexifUpdates # -# Manually replace old code in rtexif/* with new from /tmp/rt-generateLensList/* +# Manually replace old code in rtexif/* with new from /tmp/rt-generateRtexifUpdates/* # # Blame DrSlony # Please report bugs or enhancements to https://github.com/Beep6581/RawTherapee @@ -18,7 +18,7 @@ hash xmlstarlet 2>/dev/null || { echo >&2 "XMLStarlet not found, install it firs unset cam cams -tmpdir="/tmp/rt-generateLensList" +tmpdir="/tmp/rt-generateRtexifUpdates" printf '%s\n' "ExifTool version: $("$et" -ver)" "" "XMLStarlet version: $(xmlstarlet --version)" | sed 's/^/# /' @@ -30,15 +30,18 @@ mkdir -p "$tmpdir" || { printf '%s\n' "Error creating $tmpdir" ""; exit 1; } echo # Canon -printf '%s\n' "Saving ${tmpdir}/canon" -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" -sed -r -i -e '/-1\tn\/a/d' -e 's/([0-9]+)[0-9.]*\t/\1, "/' -e 's/^/ choices.insert(p_t(/' -e 's/$/"));/' -e 's| F/([0-9]+)| f/\1|' "${tmpdir}/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" +sed -r -i -e '/-1\tn\/a/d' -e 's/([0-9]+)[0-9.]*\t/\1, "/' -e 's/^/ choices.insert (p_t (/' -e 's/$/"));/' -e 's| F/([0-9]+)| f/\1|' "${tmpdir}/canon_lenses" # xmlstarlet sel -T -t -m "taginfo/table/tag[@name='EasyMode']/values/key" -v "concat(@id,' ',val)" -n < <(exiftool -listx -canon:all) | sed -r -e '/-1\tn\/a/d' -e 's/([0-9]+)[0-9.]*\t/\1] = "/' -e 's/^/ choices[/' -e 's/$/";/' +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" +sed -r -i -e 's/^/ choices[/' -e 's/\t/] = "/' -e 's/$/";/' "${tmpdir}/canon_cameras" # 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" +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" @@ -48,7 +51,7 @@ sed -r -i -e '/0 00 00\tNone/d' -e 's/^/ lenses["0/' -e 's/\t/"] = "/' -e # 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" +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" @@ -56,6 +59,6 @@ xmlstarlet sel -T -t -m "taginfo/table/tag[@name='LensType']/values/key" -v "con # 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" +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/executable_loader.in b/tools/osx/executable_loader.in index c36695d9e..dcc0cabc4 100644 --- a/tools/osx/executable_loader.in +++ b/tools/osx/executable_loader.in @@ -48,4 +48,8 @@ esac #fi #ln -sf "${app}" /tmp +# Prevent crash when directory name contains special characters +AppleLocale=`defaults read -g AppleLocale` +export LANG=${AppleLocale%@*}.UTF-8 + exec "${cwd}/rawtherapee-bin" "$@" diff --git a/tools/osx/macosx_bundle.sh b/tools/osx/macosx_bundle.sh index 40cfe195f..8b9cbccb6 100644 --- a/tools/osx/macosx_bundle.sh +++ b/tools/osx/macosx_bundle.sh @@ -154,6 +154,13 @@ ditto {"${GTK_PREFIX}","${RESOURCES}"}/share/icons/Adwaita/index.theme # cp -RL "${GTK_PREFIX}/etc/fonts" "${ETC}" # fi +# Copy the Lensfun database into the app bundle +mkdir -p "${RESOURCES}/share/lensfun" +cp /opt/local/share/lensfun/version_1/* "${RESOURCES}/share/lensfun" + +# Copy the libiomp5 license into the app bundle +cp "${PROJECT_SOURCE_DIR}/licenses/osx_libiomp5_LICENSE.txt" "${RESOURCES}" + # Install names find -E "${CONTENTS}" -type f -regex '.*/(rawtherapee-cli|rawtherapee|.*\.(dylib|so))' | while read -r x; do msg "Modifying install names: ${x}" diff --git a/tools/source_icons/scalable/HDR-thumbnail.file b/tools/source_icons/scalable/HDR-thumbnail.file new file mode 100644 index 000000000..59f729498 --- /dev/null +++ b/tools/source_icons/scalable/HDR-thumbnail.file @@ -0,0 +1 @@ +HDR-thumbnail.png,w29,actions diff --git a/tools/source_icons/scalable/HDR-thumbnail.svg b/tools/source_icons/scalable/HDR-thumbnail.svg new file mode 100644 index 000000000..ef070f380 --- /dev/null +++ b/tools/source_icons/scalable/HDR-thumbnail.svg @@ -0,0 +1,352 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/PixelShift-thumbnail.file b/tools/source_icons/scalable/PixelShift-thumbnail.file new file mode 100644 index 000000000..a62809a4d --- /dev/null +++ b/tools/source_icons/scalable/PixelShift-thumbnail.file @@ -0,0 +1 @@ +PixelShift-thumbnail.png,w18,actions diff --git a/tools/source_icons/scalable/PixelShift-thumbnail.svg b/tools/source_icons/scalable/PixelShift-thumbnail.svg new file mode 100644 index 000000000..b606b24f8 --- /dev/null +++ b/tools/source_icons/scalable/PixelShift-thumbnail.svg @@ -0,0 +1,353 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/previewmodeB-off.file b/tools/source_icons/scalable/previewmodeB-off.file new file mode 100644 index 000000000..78d96d991 --- /dev/null +++ b/tools/source_icons/scalable/previewmodeB-off.file @@ -0,0 +1 @@ +previewmodeB-off.png,w8,actions diff --git a/tools/source_icons/scalable/previewmodeB-off.svg b/tools/source_icons/scalable/previewmodeB-off.svg new file mode 100644 index 000000000..2566c37cf --- /dev/null +++ b/tools/source_icons/scalable/previewmodeB-off.svg @@ -0,0 +1,81 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/tools/source_icons/scalable/previewmodeB-on.file b/tools/source_icons/scalable/previewmodeB-on.file new file mode 100644 index 000000000..045f8a31b --- /dev/null +++ b/tools/source_icons/scalable/previewmodeB-on.file @@ -0,0 +1 @@ +previewmodeB-on.png,w8,actions diff --git a/tools/source_icons/scalable/previewmodeB-on.svg b/tools/source_icons/scalable/previewmodeB-on.svg new file mode 100644 index 000000000..cc3faa733 --- /dev/null +++ b/tools/source_icons/scalable/previewmodeB-on.svg @@ -0,0 +1,81 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/tools/source_icons/scalable/previewmodeBC0-off.file b/tools/source_icons/scalable/previewmodeBC0-off.file new file mode 100644 index 000000000..baf7ab70a --- /dev/null +++ b/tools/source_icons/scalable/previewmodeBC0-off.file @@ -0,0 +1 @@ +previewmodeBC0-off.png,w8,actions diff --git a/tools/source_icons/scalable/previewmodeBC0-off.svg b/tools/source_icons/scalable/previewmodeBC0-off.svg new file mode 100644 index 000000000..7c29636e9 --- /dev/null +++ b/tools/source_icons/scalable/previewmodeBC0-off.svg @@ -0,0 +1,92 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + T + + diff --git a/tools/source_icons/scalable/previewmodeBC0-on.file b/tools/source_icons/scalable/previewmodeBC0-on.file new file mode 100644 index 000000000..033a88501 --- /dev/null +++ b/tools/source_icons/scalable/previewmodeBC0-on.file @@ -0,0 +1 @@ +previewmodeBC0-on.png,w8,actions diff --git a/tools/source_icons/scalable/previewmodeBC0-on.svg b/tools/source_icons/scalable/previewmodeBC0-on.svg new file mode 100644 index 000000000..7613279ec --- /dev/null +++ b/tools/source_icons/scalable/previewmodeBC0-on.svg @@ -0,0 +1,92 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + T + + diff --git a/tools/source_icons/scalable/previewmodeBC1-off.file b/tools/source_icons/scalable/previewmodeBC1-off.file new file mode 100644 index 000000000..db5e6f2e2 --- /dev/null +++ b/tools/source_icons/scalable/previewmodeBC1-off.file @@ -0,0 +1 @@ +previewmodeBC1-off.png,w8,actions diff --git a/tools/source_icons/scalable/previewmodeBC1-off.svg b/tools/source_icons/scalable/previewmodeBC1-off.svg new file mode 100644 index 000000000..1e7d3e669 --- /dev/null +++ b/tools/source_icons/scalable/previewmodeBC1-off.svg @@ -0,0 +1,81 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/tools/source_icons/scalable/previewmodeBC1-on.file b/tools/source_icons/scalable/previewmodeBC1-on.file new file mode 100644 index 000000000..1de2f604d --- /dev/null +++ b/tools/source_icons/scalable/previewmodeBC1-on.file @@ -0,0 +1 @@ +previewmodeBC1-on.png,w8,actions diff --git a/tools/source_icons/scalable/previewmodeBC1-on.svg b/tools/source_icons/scalable/previewmodeBC1-on.svg new file mode 100644 index 000000000..b4b21cd85 --- /dev/null +++ b/tools/source_icons/scalable/previewmodeBC1-on.svg @@ -0,0 +1,81 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/tools/source_icons/scalable/previewmodeBC2-off.file b/tools/source_icons/scalable/previewmodeBC2-off.file new file mode 100644 index 000000000..6073f7aac --- /dev/null +++ b/tools/source_icons/scalable/previewmodeBC2-off.file @@ -0,0 +1 @@ +previewmodeBC2-off.png,w8,actions diff --git a/tools/source_icons/scalable/previewmodeBC2-off.svg b/tools/source_icons/scalable/previewmodeBC2-off.svg new file mode 100644 index 000000000..e9f4e10f2 --- /dev/null +++ b/tools/source_icons/scalable/previewmodeBC2-off.svg @@ -0,0 +1,81 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/tools/source_icons/scalable/previewmodeBC2-on.file b/tools/source_icons/scalable/previewmodeBC2-on.file new file mode 100644 index 000000000..18229b31d --- /dev/null +++ b/tools/source_icons/scalable/previewmodeBC2-on.file @@ -0,0 +1 @@ +previewmodeBC2-on.png,w8,actions diff --git a/tools/source_icons/scalable/previewmodeBC2-on.svg b/tools/source_icons/scalable/previewmodeBC2-on.svg new file mode 100644 index 000000000..582b69fd8 --- /dev/null +++ b/tools/source_icons/scalable/previewmodeBC2-on.svg @@ -0,0 +1,81 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/tools/source_icons/scalable/previewmodeBC3-off.file b/tools/source_icons/scalable/previewmodeBC3-off.file new file mode 100644 index 000000000..1538e97f1 --- /dev/null +++ b/tools/source_icons/scalable/previewmodeBC3-off.file @@ -0,0 +1 @@ +previewmodeBC3-off.png,w8,actions diff --git a/tools/source_icons/scalable/previewmodeBC3-off.svg b/tools/source_icons/scalable/previewmodeBC3-off.svg new file mode 100644 index 000000000..f8adf9626 --- /dev/null +++ b/tools/source_icons/scalable/previewmodeBC3-off.svg @@ -0,0 +1,81 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/tools/source_icons/scalable/previewmodeBC3-on.file b/tools/source_icons/scalable/previewmodeBC3-on.file new file mode 100644 index 000000000..6dad52343 --- /dev/null +++ b/tools/source_icons/scalable/previewmodeBC3-on.file @@ -0,0 +1 @@ +previewmodeBC3-on.png,w8,actions diff --git a/tools/source_icons/scalable/previewmodeBC3-on.svg b/tools/source_icons/scalable/previewmodeBC3-on.svg new file mode 100644 index 000000000..8e92c0b35 --- /dev/null +++ b/tools/source_icons/scalable/previewmodeBC3-on.svg @@ -0,0 +1,81 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/tools/source_icons/scalable/previewmodeF-focusScreen-off.file b/tools/source_icons/scalable/previewmodeF-focusScreen-off.file new file mode 100644 index 000000000..f019c1bfb --- /dev/null +++ b/tools/source_icons/scalable/previewmodeF-focusScreen-off.file @@ -0,0 +1 @@ +previewmodeF-focusScreen-off.png,w22,actions diff --git a/tools/source_icons/scalable/previewmodeF-focusScreen-off.svg b/tools/source_icons/scalable/previewmodeF-focusScreen-off.svg new file mode 100644 index 000000000..814bc9e93 --- /dev/null +++ b/tools/source_icons/scalable/previewmodeF-focusScreen-off.svg @@ -0,0 +1,630 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/previewmodeF-focusScreen-on.file b/tools/source_icons/scalable/previewmodeF-focusScreen-on.file new file mode 100644 index 000000000..07dc7c137 --- /dev/null +++ b/tools/source_icons/scalable/previewmodeF-focusScreen-on.file @@ -0,0 +1 @@ +previewmodeF-focusScreen-on.png,w22,actions diff --git a/tools/source_icons/scalable/previewmodeF-focusScreen-on.svg b/tools/source_icons/scalable/previewmodeF-focusScreen-on.svg new file mode 100644 index 000000000..63b0e4ec8 --- /dev/null +++ b/tools/source_icons/scalable/previewmodeF-focusScreen-on.svg @@ -0,0 +1,604 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/tools/source_icons/scalable/previewmodeF-off.file b/tools/source_icons/scalable/previewmodeF-off.file new file mode 100644 index 000000000..420ff2d30 --- /dev/null +++ b/tools/source_icons/scalable/previewmodeF-off.file @@ -0,0 +1 @@ +previewmodeF-off.png,w8,actions diff --git a/tools/source_icons/scalable/previewmodeF-off.svg b/tools/source_icons/scalable/previewmodeF-off.svg new file mode 100644 index 000000000..dd4f099b9 --- /dev/null +++ b/tools/source_icons/scalable/previewmodeF-off.svg @@ -0,0 +1,92 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + F + + diff --git a/tools/source_icons/scalable/previewmodeF-on.file b/tools/source_icons/scalable/previewmodeF-on.file new file mode 100644 index 000000000..64d9940b3 --- /dev/null +++ b/tools/source_icons/scalable/previewmodeF-on.file @@ -0,0 +1 @@ +previewmodeF-on.png,w8,actions diff --git a/tools/source_icons/scalable/previewmodeF-on.svg b/tools/source_icons/scalable/previewmodeF-on.svg new file mode 100644 index 000000000..0b5ca90c5 --- /dev/null +++ b/tools/source_icons/scalable/previewmodeF-on.svg @@ -0,0 +1,92 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + F + + diff --git a/tools/source_icons/scalable/previewmodeG-off.file b/tools/source_icons/scalable/previewmodeG-off.file new file mode 100644 index 000000000..be2f098d4 --- /dev/null +++ b/tools/source_icons/scalable/previewmodeG-off.file @@ -0,0 +1 @@ +previewmodeG-off.png,w8,actions diff --git a/tools/source_icons/scalable/previewmodeG-off.svg b/tools/source_icons/scalable/previewmodeG-off.svg new file mode 100644 index 000000000..29f08ebec --- /dev/null +++ b/tools/source_icons/scalable/previewmodeG-off.svg @@ -0,0 +1,81 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/tools/source_icons/scalable/previewmodeG-on.file b/tools/source_icons/scalable/previewmodeG-on.file new file mode 100644 index 000000000..d6c82f803 --- /dev/null +++ b/tools/source_icons/scalable/previewmodeG-on.file @@ -0,0 +1 @@ +previewmodeG-on.png,w8,actions diff --git a/tools/source_icons/scalable/previewmodeG-on.svg b/tools/source_icons/scalable/previewmodeG-on.svg new file mode 100644 index 000000000..4e5e19b56 --- /dev/null +++ b/tools/source_icons/scalable/previewmodeG-on.svg @@ -0,0 +1,81 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/tools/source_icons/scalable/previewmodeL-off.file b/tools/source_icons/scalable/previewmodeL-off.file new file mode 100644 index 000000000..7a743f2a3 --- /dev/null +++ b/tools/source_icons/scalable/previewmodeL-off.file @@ -0,0 +1 @@ +previewmodeL-off.png,w8,actions diff --git a/tools/source_icons/scalable/previewmodeL-off.svg b/tools/source_icons/scalable/previewmodeL-off.svg new file mode 100644 index 000000000..ea9300e7a --- /dev/null +++ b/tools/source_icons/scalable/previewmodeL-off.svg @@ -0,0 +1,92 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + L + + diff --git a/tools/source_icons/scalable/previewmodeL-on.file b/tools/source_icons/scalable/previewmodeL-on.file new file mode 100644 index 000000000..e7b99191f --- /dev/null +++ b/tools/source_icons/scalable/previewmodeL-on.file @@ -0,0 +1 @@ +previewmodeL-on.png,w8,actions diff --git a/tools/source_icons/scalable/previewmodeL-on.svg b/tools/source_icons/scalable/previewmodeL-on.svg new file mode 100644 index 000000000..41cd85c07 --- /dev/null +++ b/tools/source_icons/scalable/previewmodeL-on.svg @@ -0,0 +1,92 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + L + + diff --git a/tools/source_icons/scalable/previewmodeR-off.file b/tools/source_icons/scalable/previewmodeR-off.file new file mode 100644 index 000000000..a18cb0f3d --- /dev/null +++ b/tools/source_icons/scalable/previewmodeR-off.file @@ -0,0 +1 @@ +previewmodeR-off.png,w8,actions diff --git a/tools/source_icons/scalable/previewmodeR-off.svg b/tools/source_icons/scalable/previewmodeR-off.svg new file mode 100644 index 000000000..2bb60f3b6 --- /dev/null +++ b/tools/source_icons/scalable/previewmodeR-off.svg @@ -0,0 +1,81 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/tools/source_icons/scalable/previewmodeR-on.file b/tools/source_icons/scalable/previewmodeR-on.file new file mode 100644 index 000000000..5901958fb --- /dev/null +++ b/tools/source_icons/scalable/previewmodeR-on.file @@ -0,0 +1 @@ +previewmodeR-on.png,w8,actions diff --git a/tools/source_icons/scalable/previewmodeR-on.svg b/tools/source_icons/scalable/previewmodeR-on.svg new file mode 100644 index 000000000..0648c48b2 --- /dev/null +++ b/tools/source_icons/scalable/previewmodeR-on.svg @@ -0,0 +1,81 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + +